SimpleDateFormat底层也没有
Calendar指定在夏令时与标准时间之间重叠的时间内解析没有时区的datetime字符串时会发生什么。
您已经观察到它将返回较晚的时间,即与夏时制相比,它似乎更喜欢标准时间。但是,行为是不确定的,所以…
java.time但是,新类确实指定发生了什么,以及如何选择重叠的另一个“小时”。
在新的API中,由于您的datetime字符串没有时区,因此您可能首先使用进行解析
LocalDateTime,然后应用时区来获取
ZonedDateTime,例如
LocalDateTime ldtEnd = LocalDateTime.parse("2016-11-06T01:56:01");ZonedDateTime zdtEnd = ldtEnd.atZone(ZoneId.of("America/Los_Angeles"));// zdtEnd is now: 2016-11-06T01:56:01-07:00[America/Los_Angeles]要查看重叠部分,您可以尝试添加一个小时:
ZonedDateTime zdtEnd2 = zdtEnd.plusHours(1);// zdtEnd2 is now: 2016-11-06T01:56:01-08:00[America/Los_Angeles]
行为是明确定义的,请参见
atZone():
在大多数情况下,本地日期时间只有一个有效偏移量。 在重叠的情况下,将 时钟调回,则有两个有效的偏移量。 此方法使用 通常对应于“
summer” 的 较早 偏移量。在间隙中,时钟向前跳,则没有有效的偏移量。取而代之的是,将本地日期时间调整为晚一些间隔时间。对于典型的一小时夏令时更改,本地日期时间将在一小时后移入通常对应于“夏季”的偏移量中。
若要获得 重叠期间 的更高偏移量 ,
请调用ZonedDateTime.withLaterOffsetAtOverlap()此方法的结果。要在存在间隙或重叠时引发异常,请使用ZonedDateTime.ofStrict(LocalDateTime,ZoneOffset, ZoneId)。
如您所见,它将始终以重叠的形式返回 较早的 时间,这与观察到的行为相反
SimpleDateFormat。如果您希望 以后的
时间重叠,请致电
withLaterOffsetAtOverlap()。
如果您不想依赖已记录的默认值,则可以始终明确:
ZoneId PT = ZoneId.of("America/Los_Angeles");LocalDateTime ldtStart = LocalDateTime.parse("2016-11-06T00:57:01");ZonedDateTime zdtStartEarly = ldtStart.atZone(PT).withEarlierOffsetAtOverlap();ZonedDateTime zdtStartLater = ldtStart.atZone(PT).withLaterOffsetAtOverlap();System.out.println(zdtStartEarly); // 2016-11-06T00:57:01-07:00[America/Los_Angeles]System.out.println(zdtStartLater); // 2016-11-06T00:57:01-07:00[America/Los_Angeles]LocalDateTime ldtEnd = LocalDateTime.parse("2016-11-06T01:56:01");ZonedDateTime zdtEndEarly = ldtEnd.atZone(PT).withEarlierOffsetAtOverlap();ZonedDateTime zdtEndLater = ldtEnd.atZone(PT).withLaterOffsetAtOverlap();System.out.println(zdtEndEarly); // 2016-11-06T01:56:01-07:00[America/Los_Angeles]System.out.println(zdtEndLater); // 2016-11-06T01:56:01-08:00[America/Los_Angeles]如您所见,对于
00:57时间而言,这没有什么区别,因为该时间不在重叠时间内。



