Amit Saxena
Amit Saxena

Reputation: 21

Convert String to Date in java - Time zone

I have a String, 2013-10-07T23:59:51.205-07:00, want to convert this to Java date object. I am getting parsing error.

date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse("2013-10-07T23:59:51.205-07:00");

Upvotes: 2

Views: 12447

Answers (7)

Akkusativobjekt
Akkusativobjekt

Reputation: 2023

The problem is that -07:00 is not a valid Time zone . The Time Zone should have this format, for example something like -0800.

Upvotes: 0

deHaar
deHaar

Reputation: 18568

You will want to use java.time nowadays, even if you are still interested in creating a java.util.Date, maybe for legacy compatibility. It has methods for that.

Why did you get a parsing error?
The error or Exception message is just mentioning an Unparseable date, but that is due to at least one of the following two reasons:

  • the single quotes around the Z in your pattern mean you are expecting a fixed character Z in the input String without any relation to the values of time in it, and would therefore not even parse the Zulu/UTC Z if it was contained in the input
  • assuming the single quotes were not present in the pattern, it would still not parse -07:00 because an upper-case Z in the pattern is meant to only parse RFC 822 time zones of the form -0700 (no colon), but then -07:00 is not formatted as expected

You can use an X in the pattern, which parses ISO 8601 time zones, such as -08; -0800; -08:00, an obviously more flexible standard…

If you insist on using an outdated API, parse the input as follows:

Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")
                    .parse("2013-10-07T23:59:51.205-07:00");

if not, parse your input with java.time and convert the result to a Date:

Date date = Date.from(
    OffsetDateTime.parse("2013-10-07T23:59:51.205-07:00")
                  .toInstant()
);

The latter example works without explicitly providing a pattern because the input String has an ISO standard format for OffsetDateTimes. One has to convert is to an Instant afterwards because the legacy compatibility methods of java.util.Date need java.time.Instants. They share the same base value: Epoch millis as long.

Without having to rely on Dates, just use the java.time classes Instant, ZonedDateTime, OffsetDateTime and LocalDateTime according to the values provided in the input.

Upvotes: 1

Rohit Jain
Rohit Jain

Reputation: 213233

Z shouldn't be inside quotes. I don't think Z would work for your given timezone. Before Java 7, I guess there wasn't any format to parse ISO 8601 format timezone with colon in between. You should use -0700 instead.

However, from Java 7 onwards, you have an option for parsing ISO 8601 format timezone using X instead of Z. See javadoc for SimpleDateFormat. Just use the following format:

// This would work from Java 7 onwards
date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")    
                     .parse("2013-10-07T23:59:51.205-07:00");

Upvotes: 4

Whome
Whome

Reputation: 10400

Use this trick to parse ISO8601 datetime format. I admit have not tried this with millisecond part within a string value maybe it gives you an extra headache. This works for Java6.

import javax.xml.bind.DatatypeConverter;
Calendar cal = DatatypeConverter.parseDateTime(strDatetime);

If am remembering correct cal instance may not use a system-default timezone. Its initialized to the origin string value timezone. If you want instance to use system timezone you can do this conversion.

   long ts = cal.getTimeInMillis();
   cal = Calendar.getInstance();
   cal.setTimeInMillis(ts);

Upvotes: 3

Masudul
Masudul

Reputation: 21961

You should use XXX for the format -07:00, instead of Z and X.

   Date sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
           .parse("2013-10-07T23:59:51.205-07:00");

Look at the example of this docs.

Upvotes: 1

Cirou
Cirou

Reputation: 1430

Your pattern is wrong, you should use the following:

date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
                        .parse("2013-10-07T23:59:51.205-07:00");                      

The 'X' indicates the Time zone in the ISO 8601 format as expressed in your String here: '.205-07:00'

For more information read the doc: SimpleDateFormat

Upvotes: 3

Scary Wombat
Scary Wombat

Reputation: 44834

try

date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
                 .parse("2013-10-07T23:59:51.205-0700");

The Z is not a literal and the timezone does not have a colon

See the examples at http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html

If java7 is being used then Z can be replaced with X and the timezone can have a colon

Upvotes: 4

Related Questions