tl; dr
现代方法使用java.time类和ISO 8601字符串。
阅读。
Instant // Represent a moment in UTC with a resolution of nanoseconds.
.ofEpochMilli(
Long.getLong( incomingText )
) // Returns a `Instant` object.
.atZone( // Adjust from UTC to some time zone. Same moment, same point on the timeline, different wall-clock time.
ZoneId.of( "Europe/Paris" )
) // Returns a `ZonedDateTime` object.
写作。
ZonedDateTime
.of(
LocalDate.of( 2018 , Month.JANUARY , 23 ) ,
LocalTime.of( 15 , 35 ) ,
ZoneId.of( "Europe/Paris" )
) // Returns a `ZonedDateTime` object.
.toInstant() // Returns an `Instant`. Adjust from a time zone to UTC. Same moment, same point on the timeline, different wall-clock time.
.toEpochMilli() // Returns a `long` integer number primitive. Any microseconds or nanoseconds are ignored, of course.
如果您的警报管理器尚未现代化以处理java.time对象,请使用添加到旧类中的新方法在旧类与现代类之间进行转换。
java.util.Date d = java.util.Date.from( instant ) ;
…和…
Instant instant = d.toInstant() ;
java.time
麻烦的旧日期时间类已由java.time类取代。
对于UTC中的分辨率(以纳秒为单位)的时间,请使用Instant。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
您只需要毫秒即可满足需求,因此请截断所有微秒和纳秒。
Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ;
要确定日期和时间,需要一个时区。 时区对于确定日期至关重要。 在任何给定时刻,日期都会在全球范围内变化。 例如,法国巴黎午夜过后的几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天”。
如果未指定时区,则JVM隐式应用其当前的默认时区。 该默认值可能会在运行时(!)期间随时更改,因此您的结果可能会有所不同。 最好将您的期望/期望时区明确指定为参数。
以YearQuarter格式指定正确的时区名称,例如YearQuarter、YearQuarter或ZonedDateTime。切勿使用3-4字母缩写,例如EST或IST,因为它们不是真实的时区,不是标准化的,甚至也不是唯一的( !)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果要使用JVM的当前默认时区,请提出要求并作为参数传递。 如果省略,则会隐式应用JVM的当前默认值。 最好明确一点,因为在运行时的任何时候都可以通过JVM中任何应用程序的任何线程中的任何代码来更改默认值。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
或指定一个日期。 您可以用数字设置月份,一月至十二月的理智编号为1-12。
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
或者,最好使用预定义的YearQuarter枚举对象,一年中的每个月使用一个。 提示:在整个代码库中使用这些YearQuarter对象而不是仅使用整数,可以使您的代码更具自记录性,确保有效值并提供类型安全性。
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
结合一天中的时间YearQuarter。
LocalTime lt = LocalTime.of( 14 , 0 ) ;
将它们全部包装为YearQuarter对象。
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
通过提取YearQuarter调整为UTC。
Instant instant = zdt.toInstant() ;
从UTC 1970年第一时刻的纪元参考开始,提取所需的毫秒数。 同样,请注意,提取毫秒时,YearQuarter中的任何微/纳微都会被忽略。
long milliseconds = instant.toEpochMilli() ; // Be aware of potential data loss, ignoring any microseconds or nanoseconds.
使用YearQuarter类从存储中读取毫秒数作为文本。
long milliseconds = Long.getLong( incomingText ) ;
Instant instant = Instant.ofEpochMilli( milliseconds ) ;
要通过特定地区(时区)的人们所使用的挂钟时间的镜头来查看该时刻,请应用YearQuarter以获得ZonedDateTime。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
要生成表示该值的文本,请使用YearQuarter自动进行本地化。
提示:考虑将日期时间值以标准ISO 8601格式而不是毫秒数形式写入存储。 毫秒不能被人类有意义地读取,这使得调试和监视变得棘手。
String output = instant.toString() ;
2018-10-05T20:28:48.584Z
Instant instant = Instant.parse( 2018-10-05T20:28:48.584Z ) ;
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧旧日期时间类,例如YearQuarter、YearQuarter和YearQuarter。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。 并在Stack Overflow中搜索许多示例和说明。 规格为JSR 310。
您可以直接与数据库交换java.time对象。 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。 不需要字符串,也不需要YearQuarter类。
在哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10,Java SE 11和更高版本-标准Java API的一部分,具有捆绑的实现。Java 9添加了一些次要功能和修复。
Java SE 6和Java SE 7大多数Java.time功能都在ThreeTen-Backport中反向移植到Java 6和7。
安卓系统更高版本的Android捆绑了java.time类的实现。
对于早期的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。 请参阅如何使用ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目为将来可能在java.time中添加内容提供了一个试验场。 您可能会在这里找到一些有用的类,例如YearQuarter、YearQuarter、YearQuarter等。