Определение повторяющейся даты / времени из-за перехода на летнее время - PullRequest
1 голос
/ 13 июня 2019

Я пытаюсь разобрать дату из строки.

Я бы хотел определить случай, когда из-за перехода на летнее время часы возвращаются назад, и время фактически «повторяется» в один и тот же день.

Например, исходя из летнего времени Великобритании, часы возвращаются на час в 2 часа ночи, 27 октября 2019 года.

Таким образом:

  • 12:30 - 27.10.10 2019 г.
  • Через час - 1:30 27.10.109 г.
  • Через час - 1:30 27.10.2009 (по состоянию на 2 часа мы вернулись на час назад), * ​​1014 *
  • Через час - 2:30 27 октября 2019 года.

Следовательно, «1:30 AM 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;
}

1 Ответ

2 голосов
/ 13 июня 2019
    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
...