Как получить OffsetDateTime-> LocalDateTime и сохранить это как UT C? - PullRequest
0 голосов
/ 10 января 2020

Я не нашел подходящего ответа для своей проблемы даже после долгих поисков. Это класс DateConvertUtil в Java API. Это своего рода задача рефакторинга / функции.

У меня есть метод, который анализирует данную строку даты, форматирует ее с помощью другого метода и возвращает LocalDateTime (это должно быть - слишком много зависимостей) ).

Я хочу получить часовой пояс пользователя, преобразовать (или, возможно, нет) в LocalDateTime, НО не хочу сохранять LocalDateTime, но UT C каждый раз.

Моя проблема сейчас в том, как подойти к этому. Я не вижу смещения.

Парсер работал раньше, но только для LocaldateTime, форматер тоже работает.

Пока у меня

    public static LocalDateTime parseIso8601(String date) {
        if (date == null || date.isEmpty() || date.trim().equalsIgnoreCase("") || date.length() < 10) throw new
                IllegalArgumentException("Date cannot by empty or smaller than 10 characters for parsing! Minimum date " +
                "is yyyy-MM-dd");


        LocalDateTime localDateTime;
        OffsetDateTime offsetDateTime = OffsetDateTime.now();
        offsetDateTime.toInstant().atZone(ZoneOffset.UTC);

        localDateTime = offsetDateTime.toLocalDateTime();

        return localDateTime.parse(date, buildIso8601Formatter());

Итак, я прочитал кое-что о ZonedDateTime и метках времени, но, возможно, я просто не могу думать прямо.

Я ценю любую помощь.

1 Ответ

1 голос
/ 10 января 2020

Это не очень понятно. Вы можете получить что-то вроде следующего:

    ZoneId userTimeZone = ZoneId.systemDefault();

    String date = "2019-12-25";

    LocalDateTime localDateTime = LocalDate.parse(date).atStartOfDay();
    System.out.println("localDateTime: " + localDateTime);

    OffsetDateTime utcDateTime = localDateTime.atZone(userTimeZone)
            .toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC);
    System.out.println("utcDateTime: " + utcDateTime);

Когда я запускаю этот фрагмент в моем часовом поясе (Европа / Копенгаген), вывод:

localDateTime: 2019-12-25T00:00
utcDateTime: 2019-12-24T23:00Z

Вы сказали:

Я хочу получить часовой пояс пользователя,…

Способ сделать это отличается. В автономном приложении вы можете попробовать ZonedId.systemDefault(), как в приведенном выше коде. Он дает вам часовой пояс по умолчанию для JVM, который может совпадать или не совпадать с тем, что собирается сделать пользователь. И настройку можно изменить в любой момент из другой части вашей программы или из другой программы, работающей в той же JVM, как и для fr agile. На сервере с пользователями в разных часовых поясах ZoneId.systemDefault() не будет работать вообще. Вам нужно передать часовой пояс от какого-нибудь клиента / браузера. Есть способы, и вы можете найти способ сделать это в своих настройках.

... НО не хотите сохранять LocalDateTime, но UT C каждый раз.

Это хорошо, рекомендуется использовать UT C. Опять же, способ сделать это зависит от вашей настройки. При сохранении в базе данных SQL вы можете сохранить либо OffsetDateTime, либо Instant (при условии, что вы используете драйвер, совместимый с JDB C 4.2, что весьма вероятно), поэтому приведенного выше кода может быть достаточно. Если вам нужно сохранить дату и время в виде строки, используйте Instant.toString() для создания строки в формате ISO 8601. Я не рекомендую использовать для вас LocalDateTime дату и время в UT C, так как он сам «не знает», что он в UT C, что делает риск ошибки слишком большим. Другие примеры:

    Instant utcInstant = localDateTime.atZone(userTimeZone).toInstant();
    System.out.println("utcInstant: " + utcInstant);

    String utcDateTimeString = utcDateTime.toString();
    System.out.println("utcDateTimeString: " + utcDateTimeString);
utcInstant: 2019-12-24T23:00:00Z
utcDateTimeString: 2019-12-24T23:00Z

Имя utcInstant действительно избыточно или бессмысленно, поскольку Instant с одной стороны не зависит от часовых поясов, с другой стороны всегда печатает в UT C. Я не мог придумать лучшего имени, извините. Во всяком случае, это хорошо для хранения, если вы можете в вашей настройке.

...