我在考虑使用新的Java 8 Date Time API。我进行了一些搜索,发现jodaTime是Java的一个不错选择,但仍然很想看看这个新API的工作方式。
我将所有时间都存储为UTC值,并将根据用户的时区将它们转换为本地时区特定的值。我可以找到许多文章显示如何使用新的Java Date Time API。然而,我不确定API是否会处理DST更改?或者我们有没有更好的处理日期的方法?
我正在学习新的Date API,所以想听听您关于如何处理日期时间并根据用户时区显示它的想法。
我在考虑使用新的Java 8 Date Time API。我进行了一些搜索,发现jodaTime是Java的一个不错选择,但仍然很想看看这个新API的工作方式。
我将所有时间都存储为UTC值,并将根据用户的时区将它们转换为本地时区特定的值。我可以找到许多文章显示如何使用新的Java Date Time API。然而,我不确定API是否会处理DST更改?或者我们有没有更好的处理日期的方法?
我正在学习新的Date API,所以想听听您关于如何处理日期时间并根据用户时区显示它的想法。
这取决于你使用的类:
Instant
是全球时间线(UTC)上的即时时间点,与时区无关。LocalDate
和 LocalDateTime
没有时区的概念,但调用 now()
当然会给出正确的时间。OffsetDateTime
有一个时区,但不支持夏令时。ZonedDateTime
具有完整的时区支持。它们之间的转换通常需要一个时区,因此回答你的问题:
是的,Java 8日期/时间可以处理夏令时,如果你使用得当。
OffsetDateTime
不支持夏令时,这正是我所需要的,谢谢! - Clint EastwoodlocalDateTime.atZone(zoneId_LosAngeles);
<--- 所以LocalDateTime接受时区,那么为什么这个答案说LocalDateTime没有时区的概念
? - Kanagavelu SugumarLocalDateTime
对象没有概念,不知道嵌入的日期/时间值属于哪个时区。仅仅因为该类提供了一个将存储的值转换为其他类型对象的 辅助方法,并不意味着该对象及其数据知道任何关于时区的信息。localDateTime.atZone(zoneId)
方法是一个 便利方法,使得调用比 ZonedDateTime.of(localDateTime, zoneId)
更简单,这正是它为您完成的工作,如果您 查看该方法的源代码,就会发现这一点。 - Andreas让我们使用一些代码进行测试。美国和加拿大的DST将于2015年11月1日02:00到期。
让我们从“本地”日期时间开始,即不与时间线相关并忽略时区问题。再加一个小时,我们就得到了2点钟。很有道理。
LocalDateTime localDateTime = LocalDateTime.of( 2015 , Month.NOVEMBER , 1 , 1 , 0 ); // 1 AM anywhere. Not tied the timeline nor to any time zone.
LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours( 1 ); // 2 AM anywhere, in no particular time zone, ignoring DST.
America/Los_Angeles
中。ZoneId zoneId_LosAngeles = ZoneId.of( "America/Los_Angeles" );
ZonedDateTime before = localDateTime.atZone( zoneId_LosAngeles ); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line.
ZonedDateTime after = before.plusHours( 1 ); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015.
将数据输出到控制台。
System.out.println( "localDateTime : " + localDateTime );
System.out.println( "localDateTimeOneHourLater : " + localDateTimeOneHourLater );
System.out.println( "before : " + before );
System.out.println( "after : " + after );
localDateTime : 2015-11-01T01:00
localDateTimeOneHourLater : 2015-11-01T02:00
但是,当夏令时结束那天应用时区后,我们会得到不同的结果。请注意,时间保持为01:00
,但与UTC的偏移量从-07:00
变为-08:00
。
before : 2015-11-01T01:00-07:00[America/Los_Angeles]
after : 2015-11-01T01:00-08:00[America/Los_Angeles]
before
和after
对象作为Instant
对象访问来实现。然后System.out.println
隐式地调用toString
方法。System.out.println( "before.toInstant : " + before.toInstant() );
System.out.println( "after.toInstant : " + after.toInstant() );
运行时。
before.toInstant : 2015-11-01T08:00:00Z
after.toInstant : 2015-11-01T09:00:00Z
java.time 框架是内置于 Java 8 及更高版本中的。这些类替代了老旧的 遗留 日期时间类,例如 java.util.Date
、Calendar
和 SimpleDateFormat
。
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 可能未来添加的试验场。您可能会在这里找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
,以及更多。