如何将日期转换为毫秒

新手上路,请多包涵

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

注意:为了清楚起见,我想从 1970/1/1 格式的日期中获取毫秒。

原文由 anzure 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 686
2 个回答

您没有 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();

原文由 Luiggi Mendoza 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

时区

接受的答案是正确的,只是它忽略了 time zone 的关键问题。您输入的字符串是 6:10 PM in Paris 还是 Montréal?还是 协调世界时

使用 正确的时区名称。通常是大陆加上城市/地区。例如, "Europe/Oslo" 。避免使用既不标准化也不唯一的 3 或 4 字母代码。

java.time

现代方法使用 java.time 类。

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

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

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

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

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

 Instant instant = zdt.toInstant() ;

现在我们可以得到你想要的毫秒数,从 UTC 1970 年第一时刻的纪元参考开始,1970-01-01T00:00Z。

 long millisSinceEpoch = instant.toEpochMilli() ;

注意可能的数据丢失。 Instant 对象能够携带微秒或纳秒,比毫秒更精细。在获取毫秒数时,将忽略秒的小数部分。


关于 java.time

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

现在处于 维护模式Joda-Time 项目建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 中搜索许多示例和解释。规范是 JSR 310

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

在哪里获取 java.time 类?

ThreeTen-Extra 项目用附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuarter 等等


乔达时间

更新: Joda-Time 项目现在处于 维护模式,团队建议迁移到 java.time 类。我将保留此部分作为历史记录。

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

java.util.Date、.Calendar 和 .SimpleDateFormat 类是众所周知的麻烦、混乱和缺陷。避开他们。使用 Joda-Time 或 Java 8 内置的 java.time 包(受 Joda-Time 启发)。

国际标准化组织 8601

您的字符串几乎是 ISO 8601 格式。斜杠需要是连字符,中间的空格应该替换为 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();

原文由 Basil Bourque 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题