如何在夏令时内验证本地日期时间?

IT小君   2022-01-05T05:06:29

Mar 12, 2017 02:39:00 "America/Chicago"不存在。当我将日期和时间设置为此值时,它不会失败。时间设置为Mar 12, 2017 03:39:00一个小时后。我怎么能得到通知,这个时间不存在。这是时间向前跳跃的方式

01:59:59
3:00:00

如您所见02:39:00,此日期永远不会存在。

这是我正在使用的代码

package com.company;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {

    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.of("America/Chicago");
        ZonedDateTime dateTimeStart = ZonedDateTime.of(2017, 1, 1, 15, 39, 0, 0, ZoneId.of("America/Chicago"));
        ZonedDateTime dateTimeStartUtc = dateTimeStart.withZoneSameInstant(ZoneOffset.UTC);

        ZoneId zoneIdDst = ZoneId.of("America/Chicago");
        ZonedDateTime dateTimeStartDst = ZonedDateTime.of(2017, 3, 12, 2, 39, 0, 0, ZoneId.of("America/Chicago"));
        ZonedDateTime dateTimeStartUtcDst = dateTimeStart.withZoneSameInstant(ZoneOffset.UTC);
        int y = 90;
    }
}
评论(2)
IT小君

您的示例不会因为ZonedDateTime.of(..)调整日期时间而引发异常javadoc的状态

这将创建一个尽可能与输入本地日期时间匹配的分区日期时间。时区规则,例如夏令时,意味着并非每个本地日期时间都对指定区域有效,因此本地日期时间可能会被调整。

您可以ZonedDateTime#ofStrict(LocalDateTime, ZoneOffset, ZoneId)用来执行验证。

获取严格验证本地日期时间、偏移量和区域 ID 组合的 ZonedDateTime 实例。

这将创建一个分区日期时间,确保偏移量根据指定区域的规则对本地日期时间有效。如果偏移量无效,则抛出异常。

您首先需要构建一个LocalDateTime. 然后你会得到ZoneOffsetZoneId的本地日期时间。然后,您可以将所有三个都提供给ofStrict.

例如,

ZoneId zoneId = ZoneId.of("America/Chicago");
LocalDateTime ldt = LocalDateTime.of(2017, 3, 12, 2, 39, 0, 0);
ZoneOffset zoneOffset = zoneId.getRules().getOffset(ldt);
ZonedDateTime zdt = ZonedDateTime.ofStrict(ldt, zoneOffset, zoneId);

会扔

Exception in thread "main" java.time.DateTimeException: LocalDateTime '2017-03-12T02:39' does not exist in zone 'America/Chicago' due to a gap in the local time-line, typically caused by daylight savings
    at java.time.ZonedDateTime.ofStrict(ZonedDateTime.java:484)
2022-01-05T05:06:30   回复
IT小君

这里是一个没有抛出异常验证。如果 aLocalDateTime在给定的时区内有效,您只需要询问区域规则

public static boolean isValid(LocalDateTime ldt, ZoneId zoneId) {
    return !zoneId.getRules().getValidOffsets(ldt).isEmpty();
}
2022-01-05T05:06:30   回复