繁体   English   中英

Java 8 的新 Java 日期时间 API 是否会处理 DST?

[英]Does Java 8's new Java Date Time API take care of DST?

我正在考虑使用新的java 8 Date Time API 我用谷歌搜索了一下,发现 jodaTime 是 Java 的不错选择,但仍然有兴趣了解这个新 API 是如何工作的。

我将所有时间以 UTC 值存储在我的数据存储中,并将根据用户的时区将它们转换为本地时区特定值。 我可以找到许多展示如何使用新的 Java 日期时间 API 的文章。 但是我不确定 API 是否会处理 DST 更改? 或者我们有更好的处理 Date 的方法吗?

我只是在学习新的 Date API ,所以想听听您对处理 DateTime 并根据用户时区显示它的想法。

这取决于您使用哪个类:

  • Instant是全球时间轴 (UTC) 上的一个瞬时点,与时区无关。
  • LocalDateLocalDateTime没有时区的概念,但调用now()当然会给你正确的时间。
  • OffsetDateTime有一个时区,但不支持夏令时。
  • ZonedDateTime具有完整的时区支持。

它们之间的转换通常需要一个时区,所以要回答你的问题:

是的,如果您使用得当,Java 8 日期/时间可以处理 DST。

安德烈亚斯的答案是正确的。

示例代码

让我们用一些代码来测试一下。 美国和加拿大的夏令时将于今年 2015 年 11 月 1 日 02:00 到期。

让我们从“本地”日期时间的凌晨 1 点开始,这意味着不受时间线限制并忽略时区问题。 再增加一个小时,我们就到了凌晨 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.

接下来我们得到具体的,具有特定的时区。 我们将凌晨 1 点带到任何地方并将其放入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.

现在增加一个小时,看看我们得到了什么。 如果忽略 DST,我们将得到凌晨 2 点。 如果遵守 DST,我们将得到凌晨 1 点……当到达凌晨 2 点时,挂钟时间跳回到凌晨 1 点,但与 UTC 有新的偏移。 这在秋季(秋季)通俗地称为“回退”

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 );

运行时,我们得到这个输出。 没有时区,凌晨 1 点 + 1 小时 = 凌晨 2 点。 请记住,这些是“本地”日期时间值,而不是 UTC 它们只代表日期时间的模糊概念,而不是时间线上的实际时刻。

localDateTime : 2015-11-01T01:00
localDateTimeOneHourLater : 2015-11-01T02:00

但是在 DST 到期当天应用时区,我们得到不同的结果。 请注意一天中的时间如何保持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]

如果我们调整到 UTC,这也许会更清楚、更容易验证。 我们可以简单地通过将beforeafter对象作为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 中的日期时间类型表,现代和传统


关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar ,和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 的试验场。 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

是的,Java API 将考虑 DST 更改。

本教程很好地解释了如何在时区之间转换日期以及如何选择正确的类来表示日期: https : //docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

您还可以查看代表每个区域规则的类: http : //docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html

特别是,此方法可以告诉您某个特定时刻是否处于夏令时: http : //docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#isDaylightSavings-java.time 。立即的-

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM