【问题标题】:How to detect an ambiguous DST overlap?如何检测不明确的 DST 重叠?
【发布时间】:2017-04-04 14:41:50
【问题描述】:

夏令时结束时,时钟会倒退 1 小时。这意味着 2017 年 11 月 5 日将有 2 个01:30 AM。所以这是它的工作方式

01:59:58
01:59:59
01:00:00
01:00:01

如您所见,当时间接近 02:00:00 时,它会倒退 1 小时到 01:00:00。这意味着 11 月 5 日会有一小时的重叠。我需要检测给定的时间是否在重叠期内?

【问题讨论】:

  • 您是否尝试过使用 joda 时间库解析这些值?我知道在处理时间变化前后的日期时我遇到了库中的一个特定异常,因此它可能会提供一些检测它的背景。我不确定joda time的内部java版本如何处理这种情况。

标签: java java-8


【解决方案1】:

类似于您之前的 SO 帖子中的my answer,询问区域规则即可:

public static boolean isAmbivalent(LocalDateTime ldt, ZoneId zoneId) {
    return zoneId.getRules().getValidOffsets(ldt).size() > 1;
}

使用示例:

LocalDateTime ldt = LocalDateTime.of(2017, 11, 5, 1, 30);
ZoneId zoneId = ZoneId.of("America/Chicago");
System.out.println(isAmbivalent(ldt, zoneId)); // true, offsets either -5:00 or -6:00

【讨论】:

    【解决方案2】:

    如果您对transition rules 感兴趣,那么以下内容可能会对您有所帮助:

    ZoneId yourZoneId = ...
    List<ZoneOffsetTransitionRule> transitionRules = yourZoneId.getRules()
                                                               .getTransitionRules();
    

    通过这些,您可以检查给定时间是否在规则定义的范围内或下一次转换发生的时间。

    The ZoneDateTime javadoc 还包含一些关于“间隙”和“重叠”以及相应偏移量的提示。

    如果您只对您的时间是否是夏令时感兴趣,isDaylightSavings(Instant) 可能会帮助您:

    ZoneId yourZoneId = ZoneId.of("Europe/Rome");
    Predicate<ZonedDateTime> isDaylightSavings = 
                               time -> yourZoneId.getRules()
                                                 .isDaylightSavings(time.toInstant());
    
    boolean isDaylightSaving = isDaylightSavings.test(ZonedDateTime.of(/* the time to test */, yourZoneId));
    // returns true if time is daylight savings time or false otherwise
    

    但是,这可能只有在您的时间已经是 ZonedDateTime 时才有意义。

    【讨论】:

      猜你喜欢
      • 2013-09-18
      • 2020-05-25
      • 2021-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多