【问题标题】:Identifying Repeated Date/Times due to Daylight Savings识别由于夏令时而重复的日期/时间
【发布时间】:2019-06-13 11:33:49
【问题描述】:

我正在尝试从字符串中解析日期。

我想确定由于夏令时而导致时钟倒退并且时间在同一天有效地“重复”的情况。

例如,根据英国夏令时,时钟会在 2019 年 10 月 27 日凌晨 2 点倒退一小时。

因此:

  • 2019 年 10 月 27 日上午 12:30,
  • 一小时后 - 2019 年 10 月 27 日凌晨 1:30,
  • 一小时后 - 2019 年 10 月 27 日凌晨 1 点 30 分(截至凌晨 2 点,我们返回了一个小时),
  • 一小时后 - 2019 年 10 月 27 日凌晨 2:30。

因此,“1:30AM 27/10/2019”指的是两个不同的时间。这是我试图确定的情况。

我创建了以下内容,但它使用了Date 和Calendar 类,以及一些不推荐使用的方法。我想使用新的java.time 功能来做到这一点——我希望有一个更简单的解决方案。

public static boolean isDateRepeatedDST(final Date date, TimeZone timeZone) {
    if (timeZone == null) {
        // If not specified, use system default
        timeZone = TimeZone.getDefault();
    }

    if (timeZone.useDaylightTime()) {
        // Initially, add the DST offset to supplied date
        // Handling the case where this is the first occurrence
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MILLISECOND, timeZone.getDSTSavings());

        // And determine if they are now logically equivalent
        if (date.toLocaleString().equals(calendar.getTime().toLocaleString())) {
            return true;
        } else {
            // Then try subtracting the DST offset
            // Handling the second occurrence
            calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.MILLISECOND, -timeZone.getDSTSavings());

            if (date.toLocaleString().equals(calendar.getTime().toLocaleString())) {
                    return true;
            }
        }
    }

    // Otherwise
    return false;
}

【问题讨论】:

    标签: java date date-format date-formatting


    【解决方案1】:
        ZoneId zone = ZoneId.of("Europe/London");
        ZonedDateTime dateTime = ZonedDateTime.of(2019, 10, 27, 0, 30, 0, 0, zone);
        for (int i = 0; i < 4; i++) {
            System.out.println(dateTime);
            dateTime = dateTime.plusHours(1);
        }
    

    输出:

    2019-10-27T00:30+01:00[Europe/London]
    2019-10-27T01:30+01:00[Europe/London]
    2019-10-27T01:30Z[Europe/London]
    2019-10-27T02:30Z[Europe/London]
    

    可以看到时间 01:30 是重复的,而且两次到来的偏移量是不同的。

    如果要测试某个时间是否重复:

    public static boolean isDateRepeatedDST(ZonedDateTime dateTime) {
        return ! dateTime.withEarlierOffsetAtOverlap().equals(dateTime.withLaterOffsetAtOverlap());
    }
    

    如果我们修改打印语句,我们可以在上面的循环中使用它:

            System.out.format("%-37s %s%n", dateTime, isDateRepeatedDST(dateTime));
    
    2019-10-27T00:30+01:00[Europe/London] false
    2019-10-27T01:30+01:00[Europe/London] true
    2019-10-27T01:30Z[Europe/London]      true
    2019-10-27T02:30Z[Europe/London]      false
    

    【讨论】:

    • 谢谢!我知道有一个更简单的解决方案。
    猜你喜欢
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 2012-07-09
    • 2015-07-09
    • 2017-08-28
    • 2020-09-24
    • 2017-03-02
    相关资源
    最近更新 更多