如何将日期转换为毫秒

时间:2014-10-29 17:39:52

标签: java date

我想将String myDate = "2014/10/29 18:10:45"转换为 long ms (i.e. currentinmlilies)?我在Google上查找,但我只能找到如何将 ms 转换为 date

注意:为了说清楚,我想从1970/1/1格式的日期获得ms。

4 个答案:

答案 0 :(得分:55)

您没有Date,您有String个日期。您应该将String转换为Date,然后获取毫秒数。要将String转换为Date,反之亦然,您应该使用SimpleDateFormat类。

以下是您想要/需要做的示例(假设此处不涉及时区):

String myDate = "2014/10/29 18:10:45";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(myDate);
long millis = date.getTime();

仍然要小心,因为在Java中,获得的毫秒数是所需纪元与1970-01-01 00:00:00之间的毫秒数。


使用自Java 8以来可用的新日期/时间API:

String myDate = "2014/10/29 18:10:45";
LocalDateTime localDateTime = LocalDateTime.parse(myDate,
    DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss") );
/*
  With this new Date/Time API, when using a date, you need to
  specify the Zone where the date/time will be used. For your case,
  seems that you want/need to use the default zone of your system.
  Check which zone you need to use for specific behaviour e.g.
  CET or America/Lima
*/
long millis = localDateTime
    .atZone(ZoneId.systemDefault())
    .toInstant().toEpochMilli();

答案 1 :(得分:5)

TL;博士

LocalDateTime.parse(           // Parse into an object representing a date with a time-of-day but without time zone and without offset-from-UTC.
    "2014/10/29 18:10:45"      // Convert input string to comply with standard ISO 8601 format.
    .replace( " " , "T" )      // Replace SPACE in the middle with a `T`.
    .replace( "/" , "-" )      // Replace SLASH in the middle with a `-`.
)
.atZone(                       // Apply a time zone to provide the context needed to determine an actual moment.
    ZoneId.of( "Europe/Oslo" ) // Specify the time zone you are certain was intended for that input.
)                              // Returns a `ZonedDateTime` object.
.toInstant()                   // Adjust into UTC.
.toEpochMilli()                // Get the number of milliseconds since first moment of 1970 in UTC, 1970-01-01T00:00Z.
  

1414602645000

时区

接受的答案是正确的,但它忽略了关键的时区问题。你的输入字符串是在巴黎或蒙特利尔下午6:10吗?或UTC

使用proper time zone name。通常是一个大陆加上城市/地区。例如,"Europe/Oslo"。避免使用既不标准也不唯一的3或4个字母代码。

java.time

现代方法使用 java.time 类。

改变您的输入以符合ISO 8601标准。用T替换中间的SPACE。并用连字符替换斜杠字符。在解析/生成字符串时, java.time 类默认使用这些标准格式。因此无需指定格式化模式。

String input = "2014/10/29 18:10:45".replace( " " , "T" ).replace( "/" , "-" ) ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;

与您的输入字符串一样,LocalDateTime缺少任何时区概念或从UTC偏移。如果没有区域/偏移的上下文,LocalDateTime没有实际意义。在印度,欧洲或加拿大是下午6:10吗?每个地方在不同时刻下午6:10经历时间轴上的不同点。因此,如果要确定时间轴上的特定点,则必须指定要考虑的内容。

ZoneId z = ZoneId.of( "Europe/Oslo" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;  

现在我们有一个特定的时刻,ZonedDateTime。通过提取Instant转换为UTC。 Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = zdt.toInstant() ;

现在,我们可以在UTC 1970-01-01T00:00Z的1970年第一时刻的纪元参考后获得所需的毫秒数。

long millisSinceEpoch = instant.toEpochMilli() ; 

请注意可能的数据丢失。 Instant对象能够携带微秒或纳秒,精确到毫秒。当得到毫秒计数时,将忽略一秒的更精细的小部分。


关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore


约达时间

更新: Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time课程。我将保留此部分的历史记录。

下面是相同类型的代码,但使用Joda-Time 2.5库和处理时区。

java.util.Date,.Calendar和.SimpleDateFormat类出了名的麻烦,令人困惑和有缺陷。避免他们。使用Java 8中内置的Joda-Time或java.time包(受Joda-Time启发)。

ISO 8601

您的字符串几乎采用ISO 8601格式。斜杠需要是连字符,中间的SPACE应替换为T。如果我们调整它,那么结果字符串可以直接输入构造函数,而无需指定格式化程序。 Joda-Time使用ISO 8701格式作为解析和生成字符串的默认格式。

示例代码

String inputRaw = "2014/10/29 18:10:45";
String input = inputRaw.replace( "/", "-" ).replace( " ", "T" );
DateTimeZone zone = DateTimeZone.forID( "Europe/Oslo" ); // Or DateTimeZone.UTC
DateTime dateTime = new DateTime( input, zone );
long millisecondsSinceUnixEpoch = dateTime.getMillis();

答案 2 :(得分:4)

SimpleDateFormat类允许您将String解析为java.util.Date对象。获得Date对象后,您可以通过调用Date.getTime()来获取自纪元以来的毫秒数。

完整的例子:

String myDate = "2014/10/29 18:10:45";
//creates a formatter that parses the date in the given format
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(myDate);
long timeInMillis = date.getTime();

请注意,这会为您提供long而不是双倍,但我认为这可能是您的意图。 SimpleDateFormat类的文档包含有关如何设置它以解析不同格式的信息。

答案 3 :(得分:3)

2017答案是:使用Java 8中引入的日期和时间类(并且还在[{3}}中向后移植到Java 6和7)。

如果要解释计算机时区中的日期时间字符串:

    long millisSinceEpoch = LocalDateTime.parse(myDate, DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"))
            .atZone(ZoneId.systemDefault())
            .toInstant()
            .toEpochMilli();

如果是其他时区,请填写该区域而不是ZoneId.systemDefault()。如果是UTC,请使用

    long millisSinceEpoch = LocalDateTime.parse(myDate, DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss"))
            .atOffset(ZoneOffset.UTC)
            .toInstant()
            .toEpochMilli();