Каков наилучший способ анализа даты XML в Java? - PullRequest
44 голосов
/ 26 мая 2009

Каков наилучший способ анализа даты XML в Java? Допустимые значения dateTime: 2002-10-10T12: 00: 00-05: 00 и 2002-10-10T17: 00: 00Z

Есть ли хорошая библиотека с открытым исходным кодом, которую я могу использовать, или я должен свернуть свою собственную, используя SimpleDateFormat или подобное?

Ответы [ 9 ]

72 голосов
/ 20 апреля 2011

Существует также javax.xml.bind.DatatypeConverter # parseDateTime (String xsdDateTime) , который входит в состав JDK.

39 голосов
/ 26 мая 2009

Я думаю, что вы хотите ISODateTimeFormat.dateTimeNoMillis() от Joda Time . В общем Я бы настоятельно настоятельно рекомендовал бы вам держаться подальше от встроенных классов Date / Calendar в Java. Joda Time гораздо лучше спроектирован, поддерживает неизменяемость (в частности, средства форматирования являются неизменяемыми и поточно-ориентированными) и является основой для нового API даты / времени в Java 7.

Пример кода:

import org.joda.time.*;
import org.joda.time.format.*;

class Test
{   
    public static void main(String[] args)
    {
        parse("2002-10-10T12:00:00-05:00");
        parse("2002-10-10T17:00:00Z");
    }

    private static final DateTimeFormatter XML_DATE_TIME_FORMAT =
        ISODateTimeFormat.dateTimeNoMillis();

    private static final DateTimeFormatter CHECKING_FORMAT =
        ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC);

    static void parse(String text)
    {
        System.out.println("Parsing: " + text);
        DateTime dt = XML_DATE_TIME_FORMAT.parseDateTime(text);
        System.out.println("Parsed to: " + CHECKING_FORMAT.print(dt));
    }
}

Выход:

Parsing: 2002-10-10T12:00:00-05:00
Parsed to: 2002-10-10T17:00:00.000Z
Parsing: 2002-10-10T17:00:00Z
Parsed to: 2002-10-10T17:00:00.000Z

(Обратите внимание, что оба выходных файла заканчиваются одним и тем же временем UTC. Отформатированный вывод использует UTC, потому что мы попросили об этом с помощью вызова withZone.)

6 голосов
/ 26 мая 2009

StaxMan абсолютно правильно. Чтобы использовать SimpleDateFormat, необходимо отключить слабый синтаксический анализ в каждом SimpleDateFormat и выполнить итерацию по нескольким форматам SimpleDateFormat, пока не найдете тот, который анализирует дату, не вызывая исключения. Если вы оставляете слабый анализ, вы склонны получать совпадение, когда вы на самом деле его не хотели, а лексическое пространство в XSD: DateTime оставляет некоторую гибкость в формате, который SimpleDateFormat не может обработать в одиночное выражение.

XML Schema 1.0 действительно использует ISO 8601, который Joda Time, как предлагает Jon Skeet, реализует, так что это допустимая опция.

Если вы хотите сохранить все это в собственных пакетах Java, вы также можете использовать XMLGregorianCalendar в сочетании с DatatypeFactory для анализа и создания строк XSD: Datetime.

См. DatatypeFactory.newXMLGregorianCalendar и XMLGregorianCalendar.toXMLFormat

2 голосов
/ 15 августа 2016

ТЛ; др

Instant instant = Instant.parse( "2002-10-10T17:00:00Z" );
OffsetDateTime odt = OffsetDateTime.parse( "2002-10-10T12:00:00-05:00" );

Подробнее

Остальные ответы верны, но сейчас устарели. Они используют проблемные старые классы, которые теперь вытеснены фреймворком java.time.

Нет такого понятия, как «XML dateTime». XML не определяет какой-либо тип данных, кроме текста.

Использование java.time

Входная строка соответствует стандартному форматированию ISO 8601 . Поэтому не нужно указывать шаблон форматирования, так как классы java.time по умолчанию используют ISO 8601 при разборе / генерации строк.

Instant

Вторая строка ввода оканчивается на Z, сокращенно Zulu, и означает UTC .

Класс Instant представляет момент на временной шкале в UTC с разрешением наносекунд .

String input = "2002-10-10T17:00:00Z":
Instant instant = Instant.parse( input );

OffsetDateTime

Первая входная строка содержит смещение от UTC, поэтому мы анализируем как OffsetDateTime.

String input = "2002-10-10T12:00:00-05:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input );

ZonedDateTime

Если вы имеете в виду определенный часовой пояс, а не просто смещение от UTC, примените его.

Используйте собственное имя часового пояса в формате continent/region. Никогда не используйте 3-4-буквенные сокращения, которые не являются истинными часовыми поясами, не стандартизированы и даже не уникальны (!).

ZoneId zoneId = ZoneId.of( "America/Cancun" );
ZonedDateTime zdt = odt.atZone( zoneId );

О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют старые проблемные классы даты и времени, такие как java.util.Date, .Calendar и & java.text.SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java.time.

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений.

Большая часть функций java.time перенесена в Java 6 & 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и другие.

2 голосов
/ 11 апреля 2012

См. Разобрать и отформатировать значения dateTime , хотя: - По умолчанию используется часовой пояс GMT -Не жалуется, если есть конечные не разбираемые части -Не учитывается, что по умолчанию для TimeZone выбрано «GMT», а для «GMT + xxxx»

1 голос
/ 07 мая 2014

Вы также можете использовать newXMLGregorianCalendar в javax.xml.datatype.DatatypeFactory, что дает вам подробный контроль, включая определение, был ли указан часовой пояс.

1 голос
/ 21 октября 2011

В XML Beans v2 это будет XmlDateTime.Factory.parse(dateTimeString), но это неудобно, поскольку он ожидает элемент с начальными и конечными тегами, такими как <mytime>2011-10-20T15:07:14.112-07:00</mytime>

Более простой подход - позвонить (new org.apache.xmlbeans.GDate(dateTimeString)).getDate().

1 голос
/ 29 марта 2010

http://xmlbeans.apache.org/samples/DateTime.html

Существует класс XmlDateTime. Просто выполните XMLDateTime.stringToDate (xmlDateTime).

0 голосов
/ 26 мая 2009

В идеале пакеты обработки XML, которые осведомлены о схеме (или будут использоваться в качестве основы для вещей), должны обеспечивать средства доступа для типизированного содержимого. Мне известен один (http://woodstox.codehaus.org/),, но он (пока) не предоставляет доступ к дате / времени, только более простые типы (числовые, массивы, QNames и т. Д.). Есть запрос на поддержку javax.xml.datatype.XMLGregorianCalendar .

Увы, не многие так делают. Однако, если вы используете конкретный пакет (например, XOM или JDOM и т. Д.), Не стоит задавать этот вопрос в их списке пользователей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...