Могу ли я переключаться между форматами для DateTimeFormatterBuilder? - PullRequest
0 голосов
/ 24 октября 2019

Я использую DateTimeFormatterBuilder (), чтобы преобразовать данные JSON, которые я принимаю (закомментированный код), и преобразовать их в один из двух форматов. Чтобы решить, какой формат использовать, я использую REGEX, чтобы найти любые квадраты, [], скобки (с чем-либо внутри ". *?"). После выбора правильного формата я бы проанализировал новое значение в другом объекте JSON.

Проблема в том, что моя программа либо неправильно выбирает какой формат использовать (либо REGEX и метод error), либо неt отформатировать его правильно (ошибка форматирования), не уверен, какой, и вместо этого отправляет ошибку обратно (нижняя часть кода).

Однако это только для данных с квадратными скобками. Данные без квадратных скобок обрабатываются правильно. Мне интересно, есть ли какие-либо решения / предложения, чтобы это исправить?

// 2018-11-28T13:09:00.2-04:00
def utcDateFormatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
                .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
                .appendPattern("xxx")
                .toFormatter()

// 2018-11-28T13:09:00.528-08:00[America/New_York]
def utcDateFormatterWithZone = new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
                .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true)
                .appendPattern("xxx'['VV']'")
                .toFormatter()


if (json.beginDateTime.find("\\[.*?\\]") == true) {
                object.setDate(LocalDateTime.parse("${json.beginDateTime}", utcDateFormatterWithZone).format(outFormatter))
            } else {
                object.setDate(LocalDateTime.parse("${json.beginDateTime}", utcDateFormatter).format(outFormatter))
            }

Error: Text '2019-09-26T15:01:07.941-05:00[America/New_York]' could not be parsed, unparsed text found at index 29

1 Ответ

1 голос
/ 24 октября 2019

Это встроено: DateTimeFormatter.ISO_ZONED_DATE_TIME

Это можно сделать намного проще. Встроенный DateTimeFormatter.ISO_ZONED_DATE_TIME соответствует обоим вашим форматам.

    String stringWithoutZoneId = "2018-11-28T13:09:00.2-04:00";
    String stringWithZoneId = "2018-11-28T13:09:00.528-08:00[America/New_York]";

    LocalDateTime parsedWithoutZoneId = LocalDateTime.parse(
            stringWithoutZoneId, DateTimeFormatter.ISO_ZONED_DATE_TIME);
    System.out.println(parsedWithoutZoneId);
    LocalDateTime parsedWithZoneId = LocalDateTime.parse(
            stringWithZoneId, DateTimeFormatter.ISO_ZONED_DATE_TIME);
    System.out.println(parsedWithZoneId);

Вывод этого фрагмента:

2018-11-28T13:09:00.200
2018-11-28T13:09:00.528

Используйте смещение тоже

Слово предупреждения, однако: Вы уверены, что хотите игнорировать смещения в строках? С этими смещениями строки представляют однозначные моменты времени. То, что вы получаете от разбора на LocalDateTime, - это даты, принадлежащие разным неизвестным смещениям. Я не понимаю, как вы можете надежно использовать их для чего-нибудь полезного.

Подумайте о разборе в ZonedDateTime. One-arg ZonedDateTIme.parse даже сделает это без какого-либо явного средства форматирования. Затем либо сохраните эти ZonedDateTime непосредственно в ваших объектах, либо преобразуйте в Instant и сохраните их. Instant представляет момент времени. Если вы не можете изменить тип хранимого, вы, вероятно, захотите преобразовать ZonedDateTime в UTC (или другой согласованный часовой пояс), а затем преобразовать в LocalDateTime. Все это говорит, не зная ваших реальных требований, поэтому я могу ошибаться, только я думаю, что нет.

Что пошло не так в вашем коде?

@ daggett правильно: CharSequence.find возвращаетстрока, поэтому для работы оператора if вам понадобится:

    if (json.beginDateTime.find("\\[.*?\\]") != null) {

A String никогда не может быть равен true, поэтому всегда выбирался форматер без зоны.

Ссылка

Документация DateTimeFormatter.ISO_ZONED_DATE_TIME

...