3

Im trying parse a date from a JSONObject

"timcre_not":"2013-12-11 21:25:04.800842+01"

and I parse with

mDate = new SimpleDateFormat("y-M-d h:m:s.SSSSSSZZ",  
                          Locale.ENGLISH).parse(json.getString("timcre_not"));

but the mDate value is:

Wed Dec 11 21:38:24 CET 2013

What is happening?

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
Cristian
  • 514
  • 4
  • 21
  • What is the timezone ? "As this example shows, each SimpleDateFormat instance has a TimeZone. This is because it's called upon to format instances of Date, which represents an absolute time in UTC. That is, Date does not carry time zone information. By default, SimpleDateFormat will use the system's default time zone." – Triode Jan 16 '14 at 12:48
  • Note to readers… Notice three interesting things about the example string: (1) Space instead of "T" in middle, (2) Six decimal places in fractional seconds, (3) Short time zone offset of "+01" instead of more common "+01:00". – Basil Bourque Jan 17 '14 at 05:24

2 Answers2

2

This should be the solution: Date object SimpleDateFormat not parsing timestamp string correctly in Java (Android) environment

SimpleDateFormat cannot take microseconds, only milliseconds.

Community
  • 1
  • 1
treeno
  • 2,510
  • 1
  • 20
  • 36
1

The answer by treeno is correct.

Joda-Time

As an alternative, you can use the third-party open-source Joda-Time. Joda-Time is often used to supplant the java.util.Date & Calendar classes found in Java (and Android).

ISO 8601

The string you have is loosely in ISO 8601 format. Replace that SPACE with a LATIN CAPITAL LETTER T "T" character to get a strict ISO 8601 format.

Joda-Time's DateTime class accepts an ISO 8601 string directly to its constructor. One catch: As with java.util.Date, a DateTime tracks only to the millisecond not microsecond. But in Joda-Time, rather than throw an error, the DateTime merely truncates (ignores) the extra (beyond 3) decimal places.

Example Code

Here is some example code using Joda-Time 2.3 and Java 8.

String input = "2013-12-11 21:25:04.800842+01";
String string = input.replace( " ", "T" ); // Replace SPACE with "T" for strict ISO 8601 format.

DateTime dateTimeUtc = new DateTime( string, DateTimeZone.UTC );

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeParis = new DateTime( string, timeZone );

Dump to console…

System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeParis: " + dateTimeParis );

When run…

dateTimeUtc: 2013-12-11T20:25:04.800Z
dateTimeParis: 2013-12-11T21:25:04.800+01:00

Java 8

I tried using the new java.time.* classes in Java 8 to parse your string.

ZonedDateTime zonedDateTime = ZonedDateTime.parse( string );

Unfortunately, the parser did not tolerate the time zone offset being the shortened +01. I tried the longer +01:00 and it worked. This seems to be a flaw in the Java implementation, not your string. The shortened offset is allowed in ISO 8601. While both I and RFC 3339 (a near-profile of ISO 8601) prefer using the longer +01:00, the ISO standard doe allow it and so should the java.time.* classes. I filed Bug Id: 9009717 with Oracle.

Get Better Data

If possible, suggest to the source of your date that they use the more strict and common ISO 8601 format including:

  • Use the letter "T" in place of SPACE
  • Longer time zone offset, "+01:00" rather than "+01"
Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154