Есть ли когда-нибудь разница между настройкой ZonedDateTimes с использованием функций with *, TemporalAdjusters или установкой TemporalFields? - PullRequest
0 голосов
/ 05 марта 2019

Скажем, у меня есть следующий код:

java.time.ZonedDateTime inputZonedDateTime = inputDate.toInstant().atZone(zoneId);
ZonedDateTime flattenedDateTime = inputZonedDateTime.withDayOfYear(1);

Как ни странно, этот служебный метод не существует неделями, поэтому неделями я его реализовывал так:

flattenedDateTime = inputZonedDateTime.with(java.time.temporal.ChronoField.DAY_OF_WEEK, 1);

И затемВы также можете сделать это:

flattenedDateTime = inputZonedDateTime.with(TemporalAdjusters.firstDayOfMonth());

(что также недоступно в течение нескольких недель)

Есть ли какая-либо разница между этими тремя способами корректировки даты?Я хочу убедиться, что они всегда функционально эквивалентны, так что я уверен, что я могу всегда использовать их взаимозаменяемо для этого конкретного сценария настройки ChronoUnit на 1. Тем более, что для «недели» нет служебных методов"дело.

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Я понимаю ваше замешательство.Разница не в том, что методы withXx работают иначе, чем TemporalAdjusters.Разница:

  • Первый день года и первый день месяца определены однозначно и поэтому их легко встроить в метод withXx или временный корректор.
  • Первый день недели отличается в зависимости от культуры.В некоторых местах неделя начинается в воскресенье или в другой день.Установка ChronoField.DAY_OF_WEEK в 1 устанавливает день недели в понедельник.Так что любой из методов withFirstDayOfWeek или временного регулятора firstDayOfWeek был бы опасен и дал бы некоторым пользователям удивительные результаты.

Если вы уверены, что хотите рассмотреть только неделю ISO, в котором понедельник является первым днем, inputZonedDateTime.with(ChronoField.DAY_OF_WEEK, 1) подходит для ваших целей.В противном случае правильное решение - использовать объект WeekFields и его временное поле dayOfWeek​().Установка этого поля в 1 установит первый день недели в соответствии с определением недели, которое представляет объект WeekFields.

Согласно Википедии:

  • В большинстве случаевНа Ближнем Востоке неделя начинается в субботу.
  • В Канаде, США, Индии, Японии, Тайване, Гонконге, Макао, Израиле, Египте, Южной Африке, на Филиппинах и в большинстве стран Латинской Америки она начинается в воскресенье..
  • ЕС и большинство других европейских стран, большая часть Азии и Океании используют понедельник (в соответствии с ISO).

Я пытался принять во внимание это воскресеньеможет быть первым днем ​​недели, например, в США.

Пример кода

    // Don’t set default locale from production code, it’s for demonstration only
    Locale.setDefault(Locale.forLanguageTag("ar-SD"));

    WeekFields wf = WeekFields.of(Locale.getDefault());
    DateTimeFormatter formatter = DateTimeFormatter
            .ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM)
            .withLocale(Locale.ENGLISH);

    ZonedDateTime inputZonedDateTime
            = ZonedDateTime.of(2019, 3, 3, 12, 0, 0, 0, ZoneId.of("Asia/Amman"));
    ZonedDateTime flattenedDateTime = inputZonedDateTime.with(wf.dayOfWeek(), 1);
    System.out.println("First day of week in "
            + Locale.getDefault().getDisplayCountry(Locale.ENGLISH)
            + " is " + flattenedDateTime.format(formatter));

Первый день недели в Судане - суббота, 2 марта 2019 г., 12:00:00 PM

Конечно, вы можете получить правильную локаль для WeekFields.of другим способом.Выходные данные с несколькими другими языковыми стандартами включают:

  • es-PY:

    Первый день недели в Парагвае - воскресенье, 3 марта 2019 года, 12:00:00 PM

  • мг-мг:

    Первый день недели на Мадагаскаре - понедельник, 25 февраля 2019 года, 12:00:00

Ссылка: Статья в Википедии: неделя

0 голосов
/ 05 марта 2019

Если вы задаетесь вопросом, является ли это правильным подходом для поиска:

  1. Получите мне зонированное время-дату с датой день недели, адаптированной для понедельника.

    Пример: 05-03-2019 .... -> 04-03-2019 ....

  2. Получите мне зонированное время и дату с адаптированной датойбыть первым днем ​​месяца!

    Пример: 05-03-2019 .... -> 01-03-2019 ....

Тогда ответ - да.

        ZoneId zoneID = ZoneId.of( "Europe/Belgrade" ) ;
        ZonedDateTime zoneDateTime = ZonedDateTime.now(zoneID) ;

        System.out.println(zoneDateTime.withDayOfMonth(1));
        System.out.println(zoneDateTime.withMonth(1));
        System.out.println(zoneDateTime.with(ChronoField.DAY_OF_WEEK,1));
        System.out.println(zoneDateTime.with(TemporalAdjusters.firstDayOfMonth()));
...