java.time
Java 8及更高版本中的java.time框架取代了旧的java.util.Date/.Calendar类。旧的课程被证明是麻烦,混乱和有缺陷的。避免他们。
java.time框架的灵感来自于高度成功的Joda-Time库,由JSR 310定义,由ThreeTen-Extra项目扩展,并在教程中进行了解释。
Instant
本Instant类代表在时间轴上一个时刻UTC。
java.time框架的分辨率为纳秒,或小数秒的9位数。毫秒只是小数秒的3位数。由于毫秒分辨率很常见,因此java.time包含一个方便的工厂方法。long millisecondsSinceEpoch = 1446959825213L;Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );millisecondsSinceEpoch:1446959825213即时:2015-11-08T05:17:05.213Z
ZonedDateTime
要考虑当前周和当月,我们需要应用特定时区。ZoneId zoneId = ZoneId.of ( "America/Montreal" );ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );在zoneId:America / Montreal,即:2015-11-08T00:17:05.213-05:00 [America / Montreal]
半开
在日期时间工作中,我们通常使用半开放方法来定义时间跨度。开头是包容性的,而结尾是独家的。而不是试图确定一周(或月)结束的最后一个瞬间,我们得到的第一个瞬间以下星期(或月)。所以一个星期从周一的第一时刻运行,并上升到但不包括在第一时刻以下星期一。
我们是一周的第一天,也是最后一天。java.time框架包括用于该with方法和ChronoField枚举的工具。
默认情况下,java.time使用ISO 8601标准。所以星期一是一周的第一天(1),星期日是最后一天(7)。ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );那个星期从:2015-11-02T00:17:05.213-05:00 [美国/蒙特利尔]到2015-11-09T00:17:05.213-05:00 [美国/蒙特利尔]
哎呀!查看这些值的时间。我们想要一天的第一时刻。一天的第一时刻并不总是00:00:00.000因为夏令时(DST)或其他异常现象。所以我们应该让java.time代表我们进行调整。要做到这一点,我们必须通过LocalDate课程。ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.firstOfWeek = firstOfWeek.toLocalDate ().atStartOfDay ( zoneId );ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );那个星期从:2015-11-02T00:00-05:00 [美国/蒙特利尔]到2015-11-09T00:00-05:00 [美国/蒙特利尔]
同月也一样。ZonedDateTime firstOfMonth = zdt.with ( ChronoField.DAY_OF_MONTH , 1 );firstOfMonth = firstOfMonth.toLocalDate ().atStartOfDay ( zoneId );ZonedDateTime firstOfNextMonth = firstOfMonth.plusMonths ( 1 );该月的运行时间为:2015-11-01T00:00-04:00 [美国/蒙特利尔]至2015-12-01T00:00-05:00 [美国/蒙特利尔]
YearMonth
查看一对时刻是否在同一个月的另一种方法是检查相同的YearMonth值。
例如,假设thisZdt并且thatZdt都是ZonedDateTime对象:boolean inSameMonth = YearMonth.from( thisZdt ).equals( YearMonth.from( thatZdt ) ) ;
毫秒
我强烈建议不要在几毫秒之内完成你的日期工作。这确实是日期时间类往往在内部工作的方式,但我们有一些原因。处理来自时代的计数是笨拙的,因为人们无法理解这些值,因此调试和记录很困难且容易出错。而且,正如我们已经看到的,可能会有不同的决议; 旧的Java类和Joda-Time库使用毫秒,而像Postgres这样的数据库使用微秒,现在java.time使用纳秒。
你会处理文本作为位,还是你让类,如String,StringBuffer和StringBuilder处理这样的细节?
但是,如果你坚持,从一个ZonedDateTime得到一个Instant,并从那里得到一个毫秒计数从纪元。但请记住,此调用可能意味着数据丢失。您ZonedDateTime/中可能包含的任何微秒或纳秒Instant将被截断(丢失)。long millis = firstOfWeek.toInstant().toEpochMilli(); // Possible data loss.
关于java.time
该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat。
要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要课程。java.sql.*
从哪里获取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的更高版本的Android捆绑java.time类的实现。
对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP ...。