What\'s the best way to parse an XML dateTime in Java? Legal dateTime values include 2002-10-10T12:00:00-05:00 AND 2002-10-10T17:00:00Z
Is there a good open source l
Ideally, XML processing packages that are schema-aware (or to be used as basis for things that are) should provide accessors for typed content. I know of one (http://woodstox.codehaus.org/), but it does not (yet) offer access to date/time, just simpler types (numeric, arrays, QNames etc). There is a request to support javax.xml.datatype.XMLGregorianCalendar.
Alas, not many do. However, it you are using specific package (like XOM or JDOM etc), it might not be a bad idea to ask this question on their user list.
Instant instant = Instant.parse( "2002-10-10T17:00:00Z" );
OffsetDateTime odt = OffsetDateTime.parse( "2002-10-10T12:00:00-05:00" );
The other Answers are correct but now outdated. They use troublesome old classes now supplanted by the java.time framework.
No such thing as an “XML dateTime”. XML does not define any data type beyond text.
The input string happens to comply with ISO 8601 standard formatting. So no need to specify a formatting pattern as the java.time classes use ISO 8601 by default when parsing/generating strings.
Instant
The second input string ends in a Z
, short for Zulu
, and means UTC.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.
String input = "2002-10-10T17:00:00Z":
Instant instant = Instant.parse( input );
OffsetDateTime
The first input string includes an offset-from-UTC, so we parse as an OffsetDateTime
.
String input = "2002-10-10T12:00:00-05:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input );
ZonedDateTime
If you have a specific time zone in mind, rather than a mere offset-from-UTC, apply that.
Use a proper time zone name in format of continent/region
. Never use the 3-4 letter abbreviations that are not true time zones, not standardized, and not even unique(!).
ZoneId zoneId = ZoneId.of( "America/Cancun" );
ZonedDateTime zdt = odt.atZone( zoneId );
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
StaxMan is absolutely correct. In order to use SimpleDateFormat, you need to turn off lax parsing in each SimpleDateFormat and iterate over several SimpleDateFormat formats until you find the one that parses the date without throwing an exception. If you leave lax parsing on, you are prone to get a match when you didn't really want one, and the lexical space of XSD:DateTime leaves some flexibility in format that SimpleDateFormat can't handle in a single expression.
XML Schema 1.0 does indeed use ISO 8601, which Joda Time, as suggested by Jon Skeet, implements so that is a valid option.
If you want to keep it all in the native Java packages, you can also use XMLGregorianCalendar in conjunction with DatatypeFactory to parse and create XSD:Datetime strings.
See DatatypeFactory.newXMLGregorianCalendar and XMLGregorianCalendar.toXMLFormat