Andreas 的The Answer 是正确的。
示例代码
让我们用一些代码来测试它。 DST in the United States & Canada 今年将于 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 点时,wall-clock time 会跳回到凌晨 1 点,但与 UTC 有新的偏移量。这在秋天(秋天)俗称"fall back"。
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,但offset-from-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,这可能会更清晰、更容易验证。我们可以简单地通过访问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.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。