Форматтер в DateTimeFormatter для формата даты ISO 8601 времени - PullRequest
0 голосов
/ 09 марта 2019

У меня вопрос по поводу DateTimeFormatter форматеров.

В SWAPI (https://swapi.co/documentation#people) вы можете прочитать для дат created и edited, что формат выглядит примерно так:

2014-12-09T13:50:51.644000Z

И описание для этих дат: enter image description here

Но в документе Класс DateTimeFormatter в предопределенных разделах форматирования , я не вижу ни одного форматера, соответствующего примеру дат SWAPI.

Проблема заключается в том, что при попытке разобрать его работает с SSSSSS :

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'")

И с nnnnnn :

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnn'Z'")

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

1 Ответ

1 голос
/ 10 марта 2019

В зависимости от вашей ситуации вам может вообще не потребоваться указывать форматер. Классы java.time анализируют (и печатают) формат ISO 8601 по умолчанию, то есть без какого-либо явного средства форматирования. Как сказано в описании на вашем изображении, это формат, который вы получили.

Однако два предопределенных форматера, на которые вы ссылаетесь, соответствуют вашему примеру:

  1. ISO_INSTANT
  2. ISO_OFFSET_DATE_TIME

Какой из них использовать, зависит от любых требований к типу, в который вы хотите разобрать строку. Проще всего разобраться в Instant. Не указывайте форматер, просто используйте Instant.parse:

    String swapiCreatedString = "2014-12-09T13:50:51.644000Z";
    Instant created = Instant.parse(swapiCreatedString);
    System.out.println("Created " + created);

Выход:

Создано 2014-12-09T13: 50: 51.644Z

Если вам нужно больше обработать проанализированную дату и время, например, отформатировать ее для пользователя, OffsetDateTime предлагает больше возможностей:

    OffsetDateTime created = OffsetDateTime.parse(swapiCreatedString);

Опять же, синтаксический анализатор не нужен. Вывод идентичен вышеуказанному.

Я полагаю, что причины, по которым вы не видите совпадения двух упомянутых форматеров, включают:

  • Ни один из примеров не содержит доли секунды, но средства форматирования принимают от 0 до 9 десятичных знаков (включительно) доли секунды.
  • Пример смещения даты и времени имеет смещение +01:00. Вы не могли знать, что Z также работает как смещение. Он произносится как «зулу» и обозначает UTC.

Чтобы ответить на ваш вопрос более прямо: ни один из ваших форматов не является правильным. Поскольку, как я сказал, Z - это смещение, вы захотите проанализировать его как таковое, а не как литерал, чтобы получить информацию о смещении из строки. Без этого вы не знали бы, по какому смещению интерпретировать 13: 50: 51.644. .SSSSSS является правильным для доли секунды, в то время как .nnnnnn означает наносекунду секунды и здесь является неправильным. В секунду есть 10 ^ 9 наносекунд, поэтому n работает, только если есть 9 цифр наносекунд. Может быть, ваш собственный пример дает лучшую иллюстрацию:

    // nnnnnn is incorrect
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnn'Z'");
    String swapiCreatedString = "2014-12-09T13:50:51.644000Z";
    LocalDateTime created = LocalDateTime.parse(swapiCreatedString, formatter);
    System.out.println("Created " + created);

Создано 2014-12-09T13: 50: 51.000644

Вы видите, что 51.644 секунды были неправильно изменены на 51.000644.

...