Дата парсинга в другом возможном формате

Мне нужно разобрать String на метку времени в формате UTC. String может иметь такой формат:

  • YYYY-MM-DDThh:mm:ss.sssZ
  • YYYY-MM-DDThh:mm:ss.sss+/-hh:mm
  • YYYY-MM-DDThh:mm:ss.sss (рассматривается в UTC, поэтому добавьте Z в конце)

Как лучше всего это сделать и избежать:

    try {
        firstDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
    } catch (DateTimeParseException e) {
        try {
            secondDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
        } catch (DateTimeParseException e2) {
                thirdDateTimeFormatter.parse(string, Instant::from).toEpochMilli();
        }
    }

Проверить длину строки?

StephaneM 31.07.2018 11:11

Может быть, использовать regex, чтобы сначала определить тип, а потом разобрать его?

lucumt 31.07.2018 11:11
Regex был бы лучшим вариантом, чтобы сначала протестировать формат, а затем проанализировать.
Ashu 31.07.2018 11:11

В этом вопросе явно используется java.time, современный API даты и времени Java, поэтому он не может быть дубликатом вопроса о старом и давно устаревшем классе SimpleDateFormat.

Ole V.V. 04.08.2018 23:45
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Возможны разные варианты. Вот простой:

private static DateTimeFormatter formatter 
        = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS[XXX]")
                .withZone(ZoneOffset.UTC);

public static Instant parse(String offsetDateTimeString) {
    return OffsetDateTime.parse(offsetDateTimeString, formatter).toInstant();
}

Давай попробуем:

    System.out.println(parse("2018-08-04T21:41:55.987Z"));
    System.out.println(parse("2018-08-04T19:41:55.987-02:00"));
    System.out.println(parse("2018-08-04T21:41:55.987"));

Это печатает:

2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z
2018-08-04T21:41:55.987Z

Квадратные скобки в строке шаблона формата окружают необязательную часть, поэтому смещение может присутствовать или нет. Смещение X использует Z для нулевого смещения, поэтому соответствует первым двум из трех ваших форматов. Чтобы указать смещение, которое будет использоваться, если его нет в строке, я установил часовой пояс по умолчанию в формате UTC на форматере.

Варианты включают:

  • Вы можете использовать предопределенные форматы ISO вместо того, чтобы писать всю строку шаблонов формата самостоятельно.
  • Поскольку мы ищем смещение, а не часовой пояс, может быть более правильным указать смещение по умолчанию, а не часовой пояс по умолчанию.

DateTimeFormatterBuilder позволяет нам делать и то, и другое. Итак, вот другой модуль форматирования, который вы можете использовать вместо этого в приведенном выше коде:

private static DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
        .appendPattern("[XXX]")
        .parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.UTC.getTotalSeconds())
        .toFormatter();

Результаты идентичны.

Другие вопросы по теме