Оригинальный ответ
Я предполагаю, что под «форматом даты XML» вы подразумеваете что-то вроде «2010-11-04T19: 14Z».Это на самом деле ISO 8601 формат.
. Вы можете конвертировать его, используя SimpleDateFormat, как другие предлагали, FastDateFormat или Joda Time , который, я считаю, был специально создан для * 1009.* с этой целью .
Редактировать: примеры кода и многое другое
Поскольку earnshae указано в комментарии, этот ответ можно улучшить с помощью примеров.
Во-первых, мы должны дать понять, что первоначальный ответ довольно устарел.Это потому, что в Java 8 введены классы для манипулирования датой и временем - пакет java.time
должен представлять интерес.Если вам повезло использовать Java 8, вам следует использовать один из них.Тем не менее, эти вещи на удивление трудно понять правильно.
LocalDate (Time), который не
Рассмотрим этот пример:
LocalDateTime dateTime = LocalDateTime.parse("2016-03-23T18:21");
System.out.println(dateTime); // 2016-03-23T18:21
Сначала может показаться, чтото, что мы используем здесь, является локальным (для даты и времени пользователя).Однако, если вы осмелитесь спросить, вы получите другой результат:
System.out.println(dateTime.getChronology()); // ISO
На самом деле это время ISO.Я считаю, что это должно читаться как «UTC», но, тем не менее, это не имеет понятия о местном часовом поясе.Поэтому мы должны считать его универсальным.
Обратите внимание, что в конце строки, которую мы анализируем, нет буквы "Z".Если вы добавите что-либо кроме даты и времени, вы получите java.time.format.DateTimeParseException
.Поэтому кажется, что этот класс бесполезен, если мы хотим проанализировать строку ISO8601.
ZonedDateTime для спасения
К счастью, есть класс, который позволяет анализировать строки ISO8601 - это java.time.ZonedDateTime .
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2016-03-23T18:21+01:00");
System.out.println(zonedDateTime); // 2016-03-23T18:21+01:00
ZonedDateTime zonedDateTimeZulu = ZonedDateTime.parse("2016-03-23T18:21Z");
System.out.println(zonedDateTimeZulu); // 2016-03-23T18:21Z
Единственная проблема в том, что вам действительно нужно использовать обозначение часового пояса.Попытка разобрать необработанное время даты (то есть «2016-03-23T18: 21») приведет к уже упомянутому RuntimeException
.В зависимости от ситуации вам придется выбирать между LocalDateTime
и ZonedDateTime
.
Конечно, вы можете легко конвертировать между этими двумя, поэтому это не должно быть проблемой:
System.out.println(zonedDateTimeZulu.toLocalDateTime()); // 2016-03-23T18:21
// Zone conversion
ZonedDateTime cetDateTime = zonedDateTimeZulu.toLocalDateTime()
.atZone(ZoneId.of("CET"));
System.out.println(cetDateTime); // 2016-03-23T18:21+01:00[CET]
Iрекомендую использовать этот класс в настоящее время.Однако, если ваше описание работы включает в себя археологию (то есть вам не повезло работать с более чем 2-летней Java 8 ...), вам, возможно, придется использовать что-то еще.
Радость SimpleDateFormat
Я не очень большой поклонник https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html,, но иногда у вас просто нет другого выбора.Проблема в том, что она не поточнобезопасна, и если вам что-то не понравится, она бросит вам в глаза проверенный Exception
(а именно ParseException
).Поэтому фрагмент кода довольно уродлив:
private Object lock = new Object();
// ...
try {
synchronized (lock) {
// Either "2016-03-23T18:21+01:00" or "2016-03-23T18:21Z"
// will be correctly parsed (mind the different meaning though)
Date date = dateFormat.parse("2016-03-23T18:21Z");
System.out.println(date); // Wed Mar 23 19:21:00 CET 2016
}
} catch (ParseException e) {
LOG.error("Date time parsing exception", e);
}
FastDateFormat
FastDateFormat
синхронизирован, поэтому вы можете по крайней мере избавиться от синхронизированного блока.Однако это внешняя зависимость.Но так как это Apache Commons Lang и он тщательно используется, я думаю, что это приемлемо.На самом деле он очень похож на SimpleDateFormat
:
FastDateFormat fastDateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mmX");
try {
Date fastDate = fastDateFormat.parse("2016-03-23T18:21+01:00");
System.out.println(fastDate);
} catch (ParseException e) {
LOG.error("Date time parsing exception", e);
}
JodaTime
С Joda-Time вы можете подумать, что следующие работы:
DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser();
LocalDateTime dateTime = LocalDateTime.parse("2016-03-23T20:48+01:00", parser);
System.out.println(dateTime); // 2016-03-23T20:48:00.000
К сожалению,независимо от того, что вы поставили в последнюю позицию (Z, +03: 00, ...), результат будет одинаковым.Понятно, что это не работает.
Что ж, вам действительно нужно проанализировать его напрямую:
DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser();
DateTime dateTime = parser.parseDateTime("2016-03-23T21:12:23+04:00");
System.out.println(dateTime); // 2016-03-23T18:12:23.000+01:00
Теперь все будет хорошо.Обратите внимание, что в отличие от одного из других ответов, я использовал dateTimeParser()
и , а не dateTime()
.Я заметил тонкую, но важную разницу в поведении между ними (Joda-Time 2.9.2).Но я предоставляю читателю возможность проверить и подтвердить.