Подтвердить что ты не робот

Преобразование даты Java в формат даты XML (и наоборот)

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

Приветствия,

Andez

4b9b3361

Ответ 1

Оригинальный ответ

Я предполагаю, что в разделе "Формат даты XML" вы имеете в виду что-то вроде "2010-11-04T19: 14Z". Фактически это ISO 8601.

Вы можете преобразовать его с помощью SimpleDateFormat, как предложили другие, FastDateFormat или с помощью Joda Time, который, я считаю, специально создан для для этой цели.

Изменить: образцы кода и многое другое

Как заработок, указанный в комментарии, этот ответ можно улучшить с помощью примеров.

Во-первых, мы должны четко указать, что исходный ответ довольно устарел. Это потому, что Java 8 вводит классы для манипулирования датой и временем - пакет java.time должен представлять интерес. Если вам посчастливилось использовать Java 8, вы должны использовать один из них. Однако эти вещи на удивление трудно получить.

LocalDate (время), которое не является

Рассмотрим следующий пример:

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]

Я рекомендую использовать эти классы в настоящее время. Однако, если ваше должностное задание включает в себя археологию (то есть вам не повезло работать с более чем 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). Но я оставляю это читателю, чтобы проверить его и подтвердить.

Ответ 2

Как уже было предложено использовать SimpleDateFormat.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String date = sdf.format(new Date());
System.out.println(date);
Date d = sdf.parse(date);

Я предполагаю, что формат/шаблон, который вы ищете, yyyy-MM-dd'T'HH:mm:ss Также посмотрите http://www.w3schools.com/schema/schema_dtypes_date.asp

Ответ 3

Используя Joda Time, вы бы сделали следующее:

DateTimeFormatter fmt = ISODateTimeFormat.dateTime(); // ISO8601 (XML) Date/time
DateTime dt = fmt.parseDateTime("2000-01-01T12:00:00+100"); // +1hr time zone
System.out.println(fmt.print(dt)); // Prints in ISO8601 format

Нить безопасная, неизменная и простая.

Ответ 4

Просто используя SimpleDateFormat в java, мы можем это сделать...

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date = sdf.parse("2011-12-31T15:05:50+1000");

Ответ 5

Метод Perfect, используйте XMLGregorianCalendar:

GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(v);
DatatypeFactory df = DatatypeFactory.newInstance();
XMLGregorianCalendar dateTime = df.newXMLGregorianCalendar(calendar);
return dateTime.toString();

Ответ 6

Вы можете анализировать и форматировать даты в любом формате с помощью SimpleDateFormat

Ответ 7

Я бы рекомендовал использовать java, встроенный в класс javax.xml.bind.DatatypeConverter. Он может обрабатывать преобразование в большинство простых xml-типов и из них. Немного громоздко для дат, которые вы должны пройти через объект Calendar, но, с другой стороны, он обрабатывает все варианты информации о зоне, которые могут встречаться в поле xml datetime.

Из xml:

    Calendar c = DatatypeConverter.parseDateTime("2015-10-21T13:25");
    Date d = c.getTime();

В xml:

    Date yourDate = new Date()
    Calendar c = Calendar.getInstance();
    c.setTime(yourDate);
    String xmlDateTime = DatatypeConverter.printDateTime(c);

Ответ 8

Чтобы соответствовать ISO8601, часовой пояс должен быть в формате + HH: MM или - HH: MM

С Simpledateformat вы должны использовать XXX вместо Z (см. ответ NovelGuy)

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");

Ответ 9

Не зная точно, какой формат вам нужен, общий ответ: вам понадобится DateFormat или SimpleDateFormat. Существует хороший учебник для здесь.