как разобрать OffsetTime для формата HHmmssZ

Я пытаюсь проанализировать строку даты в формате «HHmmssZ»,

OffsetTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmssZ")).toLocalTime()

когда я тестирую его, я получаю исключение:

java.time.format.DateTimeParseException: Text '112322Z' could not be parsed at index 6

    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.OffsetTime.parse(OffsetTime.java:327)

person Lho Ben    schedule 12.01.2020    source источник
comment
В тексте 112322 отсутствует обязательное Z в конце!   -  person Andreas    schedule 12.01.2020
comment
то же самое с z, не нужно голосовать за это :(   -  person Lho Ben    schedule 12.01.2020
comment
Если вы читали документацию, то есть javadoc DateTimeFormatter, он говорит: Смещение Z: форматирует смещение на основе количества букв шаблона. Одна, две или три буквы выводят часы и минуты без двоеточия, например «+0130». Вывод будет «+0000», если смещение равно нулю. --- Одна буква Z в строке формата не понимает Z во входных данных. Ваша строка формата должна соответствовать Z букве ZZZZZ, XXXX, XXXX, XXX, XX или X.   -  person Andreas    schedule 12.01.2020
comment
К вашему сведению: было бы хорошо, если бы текст ошибки соответствовал показанному вами коду. Первоначальный вопрос был отклонен, потому что показанная ошибка была очень очевидной, что делало вопрос совершенно бесполезным для других. Понижение удалено.   -  person Andreas    schedule 12.01.2020
comment
Отвечает ли это на ваш вопрос? Синтаксический анализ строки даты в Java [дубликат]. И/или это? ZonedDateTime игнорирует 00 для части ss.   -  person Ole V.V.    schedule 12.01.2020
comment
может быть, я рефакторинг кода, используя этот формат, так что возможно, что формат неверен с самого начала, я разместил вопрос, чтобы обменяться ...   -  person Lho Ben    schedule 12.01.2020


Ответы (2)


Все следующее вернет LocalTime со значением 11:56:01:

LocalTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmss'Z'"))
OffsetTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmssX")).toLocalTime()
OffsetTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmssXX")).toLocalTime()
OffsetTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmssXXX")).toLocalTime()
OffsetTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmssXXXX")).toLocalTime()
OffsetTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmssXXXXX")).toLocalTime()
OffsetTime.parse("115601Z", DateTimeFormatter.ofPattern("HHmmssZZZZZ")).toLocalTime()
person Andreas    schedule 12.01.2020
comment
Жесткое кодирование Z как литерала, 'Z', настоятельно не рекомендуется и дает правильный результат только потому, что вы выполняете синтаксический анализ непосредственно в LocalTime и, следовательно, не должны анализировать смещение. Все остальные линии в порядке. - person Ole V.V.; 12.01.2020
comment
@ОлеВ.В. Я не согласен. Если предполагается, что ввод должен заканчиваться на Z и он должен обрабатываться как местное время, то правильным выбором будет использование средства форматирования, обеспечивающего окончание Z. В противном случае входные данные, такие как 115601+01:00 и 115601-05:00, также будут обрабатываться как местное время 11:56:01, даже если они представляют совершенно другое фактическое время. Если ввод может иметь смещения, отличные от Z, что это значит? Следует ли игнорировать смещение, как это делает код, или время должно быть скорректировано по UTC перед его использованием? Если игнорировать, то почему там смещение? - person Andreas; 12.01.2020
comment
Меня вполне устраивают разногласия. Со своей стороны, чтобы убедиться, что строка находится в формате UTC (обозначается Z), я бы разобрал ее на OffsetTime и проверил myOffsetTIme.getOffset.equals(ZONeOFfset.UTC). - person Ole V.V.; 12.01.2020
comment
@ОлеВ.В. Но если единственное, что вы знаете, это то, что строка времени должна заканчиваться на Z, какой из этих шести других форматов вы бы выбрали? Они не поддерживают один и тот же синтаксис смещения, поэтому лучше, чтобы они все терпели неудачу, используя жесткое 'Z', чем некоторые терпели неудачу из-за неправильного синтаксиса, а другие терпели неудачу с другим сообщением из вашего пользовательского кода Java. - person Andreas; 12.01.2020

Используйте заглавную букву шаблона X для смещения, которое может использовать Z для нуля

    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HHmmssXXX");
    OffsetTime time = OffsetTime.parse("115601Z", timeFormatter);
    System.out.println(time);

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

11:56:01Z

Чтобы преобразовать в LocalTime, просто используйте .toLocalTime(), как вы уже делаете.

Для буквы шаблона Z укажите смещение как +0000

Изменить. Как вы упомянули в комментарии, противоположный способ исправить ситуацию - сохранить строку шаблона формата и проанализировать строку, соответствующую требуемому формату:

    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HHmmssZ");
    OffsetTime time = OffsetTime.parse("115601+0000", timeFormatter);

Результат такой же, как и раньше. Одна заглавная буква Z в строке шаблона формата совпадает (цитируя документацию):

… часы и минуты без двоеточия, например, «+0130».

Ссылка на сайт

Документация DateTimeFormatter и шаблон буквы.

person Ole V.V.    schedule 12.01.2020
comment
спасибо, я предпочитаю не менять формат, а использовать 115601+0000. - person Lho Ben; 12.01.2020