Мне нужно разобрать String на метку времени в формате UTC. String может иметь такой формат:
YYYY-MM-DDThh:mm:ss.sssZYYYY-MM-DDThh:mm:ss.sss+/-hh:mmYYYY-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();
}
}
Может быть, использовать regex, чтобы сначала определить тип, а потом разобрать его?
Regex был бы лучшим вариантом, чтобы сначала протестировать формат, а затем проанализировать.
В этом вопросе явно используется java.time, современный API даты и времени Java, поэтому он не может быть дубликатом вопроса о старом и давно устаревшем классе SimpleDateFormat.




Возможны разные варианты. Вот простой:
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 на форматере.
Варианты включают:
DateTimeFormatterBuilder позволяет нам делать и то, и другое. Итак, вот другой модуль форматирования, который вы можете использовать вместо этого в приведенном выше коде:
private static DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXX]")
.parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.UTC.getTotalSeconds())
.toFormatter();
Результаты идентичны.
Проверить длину строки?