By Guy


2015-06-27 16:30:48 8 Comments

I am trying to parse a String using SimpleDateFormat.

This is my current code:

public String getCreatedDateTime() {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-ddEHH:mm:ss.zzzz");
    try {
        Date date = simpleDateFormat.parse("2015-06-27T13:16:37.363Z");
        return date.toString();
    } catch (ParseException e) {
        return "Error parsing date";
    }
}

As you can see, I just put a constant in the parse() method for testing purposes.

So, this is what I am trying to parse:

2015-06-27T13:16:37.363Z

This is the SimpleDateFormat pattern that I am using:

yyyy-MM-ddEHH:mm:ss.zzzz

I keep getting the ParseException.

I know that it is proably because of the .zzzz at the end but I have no idea what .363Z might stand for so I just used some random letters. Bad idea.

I'll appreciate your help a lot. Thank you!

2 comments

@Basil Bourque 2015-06-28 04:15:28

tl;dr

Skip the formatting pattern. Standard ISO 8601 format is used by default.

Instant.parse( "2015-06-27T13:16:37.363Z" )

ISO 8601

Your string format is formally defined by the ISO 8601 standard.

Basically your Question is a duplicate of this one, Converting ISO 8601-compliant String to java.util.Date.

Alternatives

The Answer by eugenioy is correct.

But you should know that the old java.util.Date/.Calendar/java.text.SimpleDateFormat classes bundled with Java are notoriously troublesome and should be avoided.

Outmoded Classes

Those old classes are now outmoded, first by the third-party Joda-Time library, and now by the new java.time package (Tutorial) built into Java 8 and later (inspired by Joda-Time, defined by JSR 310, extended by the ThreeTen-Extra project).

Both java.time and Joda-Time use the ISO 8601 standard as their defaults when parsing/generating string representations of date-time values. So the code is simple, no need for custom formatter objects. No need for all that format twiddling that caused your Exception.

Time Zone

Both java.time and Joda-Time have a zoned date-time class that understands its assigned time zone (unlike java.util.Date). If you do not assign one, the JVM’s current default time zone is assigned.

Beware that the JVM’s current default time zone can change at any time. It can change at deployment, defaulting to whatever the host OS setting is. And it can change at any moment during runtime when any code in any thread of any app within the JVM calls TimeZone.setDefault. So better to explicitly assign a desired/expected time zone.

java.time

The Z on the end of your string is short for Zulu and means UTC. The Instant class can directly parse that format, to represent a moment on the timeline in UTC with a resolution in nanoseconds.

String input = "2015-06-27T13:16:37.363Z";
Instant instant = Instant.parse( input );

Change the time zone from UTC to some desired/expected time zone.

ZoneID zone = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontréal = instant.atZone( zone ) ;

If you really need a java.util.Date for interoperability, convert.

java.util.Date utilDate = Date.from( zdtMontréal.toInstant() ) ;

Joda-Time

The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Example code using Joda-Time 2.8.1.

String input = "2015-06-27T13:16:37.363Z" ;
DateTimeZone zone = DateTimeZone.UTC ;  //  Or: DateTimeZone.forID( "America/Montreal" ) ;
DateTime dateTime = new DateTime( input, zone ) ;

If you really need a java.util.Date for interoperability, convert.

java.util.Date date = dateTime.toDate();

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

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.

@Guy 2015-07-02 11:37:47

Thank you, your answer is very informative.

@eugenioy 2015-06-27 16:46:02

Try with this pattern (note the X at the end and the 'T' in the middle):

"yyyy-MM-dd'T'HH:mm:ss.SSSX"

From Java's SimpleDateFormat's documentation:

ISO 8601 Time zone:

...

For parsing, "Z" is parsed as the UTC time zone designator.

And, from the part where it describes the different characters:

X - Time zone - ISO 8601 time zone

EDIT

If using Android, then "X" is not supported.

You can use this pattern (note Z is a literal now):

"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

But then you'll get the date on your current timezone and would need to convert it to UTC if needed.

@Guy 2015-06-27 16:57:18

Thank you for your answer. It sadly doesn't work yet. I get IllegalArgumentException: Unknown pattern character X with your pattern. Which is weird because X clearly is a pttern characters as seen from documentation.

@eugenioy 2015-06-27 17:00:24

Which version of Java are you using? And is it the Java SE or Android?

@Guy 2015-06-27 17:03:16

I'm using jdk1.8.0_40 and this is Android.

@eugenioy 2015-06-27 17:03:51

Well, it seems the "X" is not supported on Android. I'll update my answer and include a part for Android as well.

@Guy 2015-06-27 17:09:28

Awesome, this works now. Thank you very much!

@Alain O'Dea 2015-06-27 17:23:21

You can set the timezone for parsing/formatting with simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")) to make your intent clear and avoid conversion after parsing. docs.oracle.com/javase/7/docs/api/java/text/…

@Guy 2015-06-27 22:10:24

@AlainO'Dea your comment solved even one more problem that I've had. Thank you very much.

@Alain O'Dea 2015-06-28 01:08:28

@Whiz my pleasure. I was hoping it might. That one line was the solution to many confusing bugs for me. I've seen it time and again. There's a bug that this fixes in OneLogin's SAML library. github.com/onelogin/java-saml/blob/master/src/main/java/com/‌​…. I meant to do a Pull Request, but forgot since I switched to OpenSAML instead.

Related Questions

Sponsored Content

32 Answered Questions

[SOLVED] How to parse JSON in Java

  • 2010-04-07 09:00:21
  • Muhammad Maqsoodur Rehman
  • 1564096 View
  • 993 Score
  • 32 Answer
  • Tags:   java json parsing

54 Answered Questions

[SOLVED] How to format a JavaScript date

14 Answered Questions

[SOLVED] Java string to date conversion

12 Answered Questions

[SOLVED] ISO time (ISO 8601) in Python

28 Answered Questions

[SOLVED] Converting ISO 8601-compliant String to java.util.Date

  • 2010-02-04 17:52:39
  • Ice09
  • 557721 View
  • 634 Score
  • 28 Answer
  • Tags:   java date iso8601

18 Answered Questions

26 Answered Questions

[SOLVED] How do I parse an ISO 8601-formatted date?

13 Answered Questions

[SOLVED] YYYY-MM-DD format date in shell script

6 Answered Questions

[SOLVED] Java date pattern for SQL date (ISO 9075)

Sponsored Content