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

Luk*_*101 15 java java-8 java-time

Mar 12, 2017 02:39:00 "America/Chicago"不存在.当我将日期和时间设置为此值时,它不会失败.时间设定为Mar 12, 2017 03:39:00一小时后.如何通知此时间不存在.这是时间如何向前跳跃

01:59:59
3:00:00
Run Code Online (Sandbox Code Playgroud)

正如您所见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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Sot*_*lis 13

您的示例不会抛出异常,因为会ZonedDateTime.of(..)调整日期时间.该javadoc的状态

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

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

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

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

你首先需要构建一个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);
Run Code Online (Sandbox Code Playgroud)

会抛出

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)
Run Code Online (Sandbox Code Playgroud)


Men*_*ild 7

这里验证没有抛出异常.如果a LocalDateTime在给定时区内有效,您只需要询问区域规则:

public static boolean isValid(LocalDateTime ldt, ZoneId zoneId) {
    return !zoneId.getRules().getValidOffsets(ldt).isEmpty();
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果给定时间有多个有效偏移量,此方法也会返回“true”。例如,当时钟从 04:00->03:00 调回一小时时,03:30 时间将出现两次,具有两个不同的偏移量。如果您还想检测这种情况,请更改“isValid”方法,仅在偏移量列表只有一个值的情况下返回“true”:“return zoneId.getRules().getValidOffsets(ldt).size() ==” 1;` (2认同)