Java 8';s的新Java日期时间API负责DST?

Java 8';s的新Java日期时间API负责DST?,java,datetime,datetimeoffset,Java,Datetime,Datetimeoffset,我正在考虑使用新的Java8日期时间API。我在谷歌上搜索了一下,发现jodaTime是java的不错选择,但我还是有兴趣看看这个新API是如何工作的 我正在数据存储中存储所有UTC时间值,并将根据用户的时区将其转换为本地时区特定值。我可以找到许多介绍如何使用新Java日期时间API的文章。但是,我不确定API是否会处理DST更改? 或者我们有没有更好的处理日期的方法 我正在学习新的日期API,因此我想听听您对处理日期时间并根据用户时区显示它的想法。是的,Java API将考虑DST更改 本教程

我正在考虑使用新的Java8日期时间API。我在谷歌上搜索了一下,发现jodaTime是java的不错选择,但我还是有兴趣看看这个新API是如何工作的

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


我正在学习新的日期API,因此我想听听您对处理日期时间并根据用户时区显示它的想法。

是的,Java API将考虑DST更改

本教程很好地解释了如何在时区之间转换日期,以及如何选择正确的类来表示日期:

您还可以查看这个类,它表示每个区域的规则:

特别是,此方法可以告诉您某个特定时刻是否为夏令时:

这取决于您使用的类别:

  • Instant
    是全球时间线(UTC)上的一个瞬时点,与时区无关
  • LocalDate
    LocalDateTime
    没有时区的概念,但是调用
    now()
    当然会给出正确的时间
  • OffsetDateTime
    有时区,但不支持夏令时
  • ZoneDateTime
    具有完整的时区支持
在它们之间转换通常需要一个时区,因此要回答您的问题:

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

by是正确的

示例代码 让我们用一些代码来测试它加拿大将于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点放在任何地方,把它放在美国/洛杉矶(美国西海岸)的时区

现在再加上一个小时,看看我们得到了什么。如果DST被忽略,我们将得到凌晨2点。如果遵守DST,我们将得到凌晨1点……当到达凌晨2点时,跳回到凌晨1点,但与UTC有一个新的偏移。这在口语中被称为秋天(秋天)

转储到控制台

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
,但从
-07:00
更改为
-08:00

之前:2015-11-01T01:00-07:00[美国/洛杉矶]
之后:2015-11-01T01:00-08:00[美国/洛杉矶]
如果我们调整到UTC,这可能会更清楚、更容易验证。我们只需访问
之前
之后
对象作为对象即可。然后,隐式调用该方法

跑步的时候

before.toInstant:2015-11-01T08:00:00Z
安装后:2015-11-01T09:00:00Z


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

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*

从哪里获得java.time类

  • 然后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类

    • 对于早期的Android(简而言之:是的,DST已经处理好了。Java 8日期时间API是基于Joda time创建的。@Raja我会更正您的术语以避免混淆…“本地”在日期时间工作中的意思是“对于任何地方”,如“2015年12月25日午夜开始的圣诞节”。这样的本地日期时间没有时区。事实上,除非你将其调整到特定的时区,否则它没有真正的意义。25日的午夜在巴黎比在蒙特勒尔来得早。因此,在常见的商业应用程序中,我们很少使用“本地”。您将从数据库中获取存储的日期-时间值,在UTC的业务逻辑中使用它们,并调整为
      ZonedDateTime
      ,仅用于向用户演示。感谢您提醒Orcale文档的价值:)这些链接对我更有帮助。感谢您提到
      OffsetDateTime
      不支持DST,这正是我需要的,谢谢<代码>localDateTime.atZone(洛杉矶地区)@KanagaveluSugumar,因为
      LocalDateTime
      对象不知道嵌入的日期/时间值属于哪个时区。仅仅因为该类提供了一个助手方法来将存储的值转换为不同类型的对象,并不意味着该对象及其数据对时区有任何了解。
      localDateTime.atZone(zoneId)
      方法是一种方便的方法,使得调用它比
      ZoneDateTime.of(localDateTime,zoneId)
      更简单,这正是它为您所做的,您可以通过查看该方法的源代码看到。感谢您的贡献。。。我没有
      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
      
      System.out.println( "before.toInstant : " + before.toInstant() );
      System.out.println( "after.toInstant : " + after.toInstant() );