Explain Codes LogoExplain Codes Logo

Converting ISO 8601-compliant String to java.util.Date

java
date-time-api
java-8
best-practices
Anton ShumikhinbyAnton Shumikhin·Aug 30, 2024
TLDR

To convert an ISO 8601 string to java.util.Date:

String isoString = "2023-03-25T15:30:00Z"; Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse(isoString);

The 'X' suffix seamlessly caters to the timezone in the ISO format.

Diving into Java's date-time API

Java's chronology has seen various ways to work with dates and times. For example, Java 8 introduced java.time, the modern Java API for date and time, efficiently parsing ISO 8601 strings:

// Is it Java 8 o'clock already? String isoString = "2023-03-25T15:30:00Z"; Instant instant = Instant.parse(isoString); Date date = Date.from(instant);

For offset date-times (2023-03-25T10:15:30+01:00), use OffsetDateTime:

//Geez, that's a lot of dots! OffsetDateTime odt = OffsetDateTime.parse(isoString); Instant instant = odt.toInstant(); Date date = Date.from(instant);

These features have made pattern matching of the past practically obsolete.

Unraveling the timezone puzzle

When working with ISO 8601 timezones, know your acronyms:

  • 'Z' signifies UTC.
  • 'X' accommodates ISO 8601 time zone formats.
  • For full accuracy, 'XXX' supports the extended offset format.

The java.text.SimpleDateFormat in Java 7 caters to this:

// Who needs regex when you've got date-time patterns? String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"; SimpleDateFormat sdf = new SimpleDateFormat(pattern);

Caution! SimpleDateFormat is not thread-safe; avoid redeploying it across threads.

Dealing with legacy Java versions

Stuck with a Java version before 8? SimpleDateFormat to the rescue:

// Who needs Java 8 when you've got old faithful SimpleDate? String iso8601String = "2023-03-25T15:30:00.000+0200"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); Date date = sdf.parse(iso8601String);

Refer to the SimpleDateFormat javadoc for more pattern wonderment and examples.

Outmanoeuvring compatibility issues

Compassion for Android API levels

Android versions can be finicky. If you're working with API level 7 (Android 2.1), manually parse timezone offsets. SimpleDateFormat may misunderstand 'Z':

// Dark Android sorcery at hand! String dateStr = isoString.endsWith("Z") ? isoString.replaceAll("Z", "+0000") : isoString; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); Date date = sdf.parse(dateStr);

The Joda-Time refuge

In a pre-Java 8 version and need better timezone handling? Call on Joda-Time:

DateTimeFormatter formatter = ISODateTimeFormat.dateTimeParser(); DateTime dateTime = formatter.parseDateTime(isoString); Date date = dateTime.toDate();

Advanced date-time operations

Deploying JAXB's DataTypeConverter

For XML dealings, JAXB's DataTypeConverter gives an ISO 8601-compliant parser, no questions asked:

// JAXB to the rescue...again! XMLGregorianCalendar calendar = DatatypeConverter.parseDateTime(isoString); Date date = calendar.toGregorianCalendar().getTime();

The timezone representation conundrum

When swapping between Date and OffsetDateTime or other java.time classes, always bear in mind time zone implications. Understanding the user context is paramount.

Boosting parsing performance

In use cases involving frequent parsing, consider investing in pooling date formatter instances or using DateTimeFormatter on Java 8. Notably, these classes are immutable and thread-safe.