Как совместить скобки с кодом, который они содержат?

Обновлено для исправления:

В большинстве случаев да, то же самое, см. следующий пример для Бразилии при переключении с зимнего на летнее время:

ZonedDateTime zdt = 
  ZonedDateTime.of(2015, 10, 18, 0, 30, 0, 0, 
    ZoneId.of("America/Sao_Paulo")); // switch to summer time
ZonedDateTime zdt1 = zdt.truncatedTo(ChronoUnit.DAYS);
ZonedDateTime zdt2 = zdt.toLocalDate().atStartOfDay(zdt.getZone());

System.out.println(zdt); // 2015-10-18T01:30-02:00[America/Sao_Paulo]
System.out.println(zdt1); // 2015-10-18T01:00-02:00[America/Sao_Paulo]
System.out.println(zdt2); // 2015-10-18T01:00-02:00[America/Sao_Paulo]

Усечение происходит на местный график. Если вы выберете DAYS, тогда вы выбираете полночь. Согласно javadoc , truncate() -метод, наконец, обращается к новому ZonedDateTime и сдвигает время вперед на размер зазора (1 час).

Преобразование zdt сперва до LocalDate (отключение временной части), а затем поиск его ZonedDateTime -пары в заданном часовом поясе фактически одинаково для этой ситуации.

Однако для обратного случая возврата от летнего времени до зимнего времени есть одно исключение (спасибо очень большое спасибо @Austin, который дал встречный пример). Проблема заключается в перекрытии, когда нужно решить, какое смещение использовать. Обычно класс ZonedDateTime спроектирован / задан для использования предыдущего смещения, см. Также этот отрывок из Javadoc :

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

blockquote>

Если класс ZonedDateTime, следовательно, будет следовать своей собственной спецификации то обе процедуры все равно будут эквивалентными значениям:

zdt.truncatedTo(ChronoUnit.DAYS);

должен быть эквивалентен

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withEarlierOffsetAtOverlap();

Но реальное поведение в соответствии с примером @Austin и подтверждено мной в собственном тестирование:

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withLaterOffsetAtOverlap();

Похоже на скрытую несогласованность в классе ZonedDateTime, мягко говоря. Если вы спросите меня, какой метод будет предпочтительнее, я предпочел бы защищать второй метод, хотя он намного длиннее и требует больше нажатий клавиш. Но у него есть большое преимущество, чтобы быть более прозрачным в отношении того, что он делает. Еще одна причина предпочесть второй подход:

Он действительно получает ПЕРВЫЙ момент, когда местное время равно началу дня. В противном случае при использовании первого метода вам необходимо написать:

zdt.truncatedTo(ChronoUnit.DAYS).withEarlierOffsetAtOverlap();

0
задан Vincent Nagel 16 January 2019 в 03:55
поделиться