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

时间:2017-04-04 00:18:26

标签: 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

正如您所见,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 个答案:

答案 0 :(得分:13)

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

  

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

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

  

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

     

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

您首先需要构建LocalDateTime。然后,您将获得当地日期时间ZoneOffset的{​​{1}}。然后,您可以将所有三个提供给ZoneId

例如,

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);

答案 1 :(得分:6)

这里有验证而不会抛出异常。如果LocalDateTime在给定时区内有效,您只需询问区域规则:

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