0

I'm getting a ParseException while parsing a date from String to Date object. The date string also contains a timezone. I'm using this code:

final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
System.out.print(sdf.parse("2018-01-16T00:07:00.000+05:30"));

Below is the error I'm getting:

Exception in thread "main" java.text.ParseException: Unparseable date: "2018-01-16T00:07:00.000+05:30"
    at java.text.DateFormat.parse(DateFormat.java:366)
8
  • what about the TO that exists between the date string??? you need to cater it too. Commented Jan 30, 2018 at 9:36
  • 2
    Well ... Does the parsed string follow the same format as the format specifier? Commented Jan 30, 2018 at 9:38
  • 2
    This exception happened because you are not matching the date you want to parse. Commented Jan 30, 2018 at 9:40
  • Try the answers provided in this link: stackoverflow.com/questions/17692863/… Commented Jan 30, 2018 at 10:06
  • 1
    @srp321, the answers found in the question you link to use SimpleDateFormat too, I recommend you avoid that and use java.time instead. See the modern and easy solution in the answer by Laurent B. Commented Jan 30, 2018 at 11:58

3 Answers 3

4

The format you use in SimpleDateFormat must match the input String.

Your input is 2018-01-16T00:07:00.000+05:30, which is ISO8601 compliant:

  • year-month-day (2018-01-16)
  • followed by the letter T
  • followed by hour:minutes:seconds.milliseconds (00:07:00.000)
  • followed by the UTC offset (+05:30)

Note: the offset +05:30 is not a timezone. Read this to know the difference.

Anyway, the pattern you're using ("yyyy-MM-dd HH:mm:ss z") doesn't match the input string:

  • it's missing the T between date and time
  • it's missing the milliseconds
  • there's a space before the offset
  • the correct letter to parse offsets is X (although I think that z might work, depending on the JVM version you're using; in my tests, it didn't)

So your code should be:

// use "XXX" to parse the whole offset (only one "X" will parse just `+05`, missing the `:30` part)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date d = sdf.parse("2018-01-16T00:07:00.000+05:30");

But it's much better to use the new Java 8 classes, if they're available to you:

// parse ISO8601 compliant string directly
OffsetDateTime odt = OffsetDateTime.parse("2018-01-16T00:07:00.000+05:30");

If you still need to use a java.util.Date object, it's easy to convert:

// convert to java.util.Date
Date date = Date.from(odt.toInstant());
Sign up to request clarification or add additional context in comments.

1 Comment

Very well explained answer, thanks. Agree to use the Java 8 classes. New? Only four years old. :-) Available in Java 6 and 7 too through the ThreeTen Backport.
1

Change the following:

final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
          System.out.print(sdf.parse("2018-01-16 0:07:00 +0530"));

You are trying to parse z which stands for General time zone eg GMT IST etc but you need Z zone-offset like +0530 for India.Also remove the OT between the string. Your date format should match with the pattern. Refer https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

2 Comments

RFC 822 is the ARPA Internet Text Messages specification. The format OP is using is correct according to the ISO 8601
@LaurentB see my edit..z time-zone name zone-name Pacific Standard Time; PST while Z zone-offset offset-Z +0000; -0800; -08:00; is what I am trying to say..which is just another approach to solve the problem
1

Your are using an ISO 8601 date.

Using SimpleDateFormat :

final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSSX");
System.out.print(sdf.parse("2018-01-16T00:07:00.000+05:30"));

Alertnatively, you can use the build in ISO 8601 parsing provided :

Using joda time Instant:

Instant.parse("2018-01-16T00:07:00.000+05:30")

JAVA 8 : (prefered see comment below)

https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html#parse-java.lang.CharSequence-

    System.out.println(java.time.OffsetDateTime.parse(s));

3 Comments

Instant.parse("2018-01-16T00:07:00.000+05:30") doesn't work, it throws java.time.format.DateTimeParseException
@Rahul edited as it worked with joda but java 8 Instant does not support timezones, you have to use OffsetDateTime
It’s preferred to use the Java 8 solution. Joda-Time is in maintenance mode, and SimpleDateFormat long outdated and notoriously troublesome. If using Java 6 or 7, consider adding ThreeTen Backport to your project so you can use the Java 8 solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.