3

I'm querying a JSON API that returns something like this:

{
  "created_time": "2017-01-05T16:32:29+0100",
  "updated_time": "2017-01-11T09:38:41+0100",
  "id": "23842536731240607"
}

I need to store the times in UTC format, but in order to change the timezone, I first need to parse it as a ZonedDateTime.

To convert "+0100" to "+01:00" is easy enough. But how can I parse the (created/updated)_time into a ZonedDateTime so I can convert it to UTC?

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
gtludwig
  • 5,411
  • 10
  • 64
  • 90
  • 1
    possible duplicate of [Java Time Zone When Parsing DateFormat](http://stackoverflow.com/questions/4542679/java-time-zone-when-parsing-dateformat) – SDekov Jan 12 '17 at 12:01
  • 1
    possible duplicate http://stackoverflow.com/questions/34115801/how-to-convert-any-date-time-to-utc-using-zoneddatetime-or-java-8?rq=1 – nikli Jan 12 '17 at 12:02
  • 1
    Store your dates as long values representative to the number of milliseconds in UTC. This way you can easily display them however you want later. When storing dates, UTC and timezone is irrelevant. For displaying, that is another question. – Mr. Polywhirl Jan 12 '17 at 12:03

2 Answers2

4

There are some options.

First, as you say, inserting a colon in zone offset is not that difficult. After you’ve done that, getting a ZonedDateTime is straightforward:

    ZonedDateTime zdt = ZonedDateTime.parse("2017-01-11T09:38:41+01:00");
    System.out.println(zdt);

This prints:

2017-01-11T09:38:41+01:00

Alternatively, funnily, while ZonedDateTime.parse(String) needs a colon in the offset, ZoneId.of() does not, so you may split off the offset and do:

    ZoneId zi = ZoneId.of("+0100");
    LocalDateTime ldt = LocalDateTime.parse("2017-01-11T09:38:41");
    ZonedDateTime zdt = ldt.atZone(zi);

The result is the same as before.

If you prefer not to modify your string prior to parsing it, there is also:

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
    ZonedDateTime zdt = ZonedDateTime.parse("2017-01-11T09:38:41+0100", dtf);

Also this gives the same result.

Edit: Note: I am using ZonedDateTime since you asked for this in your question. You may consider it more correct to use OffsetDateTime. Most of the code is practically the same. The version that splits off the offset would go like this:

    ZoneOffset zo = ZoneOffset.of("+0100");
    LocalDateTime ldt = LocalDateTime.parse("2017-01-11T09:38:41");
    OffsetDateTime odt = ldt.atOffset(zo);

To convert to UTC, as mentioned at end of Question, apply another ZoneOffset, the constant ZoneOffset.UTC.

OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Well let me break down the problem statement.

First if you are querying an API then it can be assumed that they are following some standard Date-Time format (even if you are creating one). Looking over the given date it looks like they follow - ** ISO 8601 - Date and time format **

So the problem is how to parse ISO 8601 - Date and time format

What are best options available ?

  • Using Joda Time.
  • Using Date Time API Java-8

    //Joda
    String jtDate = "2010-01-01T12:00:00+01:00";
    DateTimeFormatter yoda = ISODateTimeFormat.dateTimeNoMillis();
    System.out.println(parser2.parseDateTime(jtDate));
    
    //using Java 8 (As you specified - To convert "+0100" to "+01:00"    is easy enough.)
    String strDate = "2017-01-05T16:32:29+01:00";
    DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_DATE_TIME;
    TemporalAccessor convertMe = timeFormatter.parse(strDate);
    Date date = Date.from(Instant.from(convertMe));
    System.out.println(date);
    

Hope it helps :)

freesoul
  • 236
  • 1
  • 13
  • LocalDateTime is the wrong class to use here. You will be losing the offset-from-UTC information. Furthermore, the Question asks for a result in UTC. – Basil Bourque Jan 13 '17 at 17:48
  • Also I tried you Java 8 code and got `java.time.format.DateTimeParseException: Text '2017-01-05T16:32:29+0100' could not be parsed, unparsed text found at index 19` (index 19 is the `+` sign). – Ole V.V. Jan 14 '17 at 11:26
  • Better, but now your input strings are not those of the Question. The Question's inputs have no colon in the offset. – Basil Bourque Jan 16 '17 at 08:03
  • I know but user has specified that - converting "+0100" to "+01:00" is easy enough. :) So only skipped that part. – freesoul Jan 16 '17 at 08:05
  • I don't mean to pick on your Answer, but… There is no need to invoke `java.util.Date` from your java.time code. The java.time classes supplant the troublesome old legacy classes of `Date`, `Calendar`, and `SimpleDateFormat`. The old classes should be avoided altogether rather than mixed with new java.time code. The Question asks for a value in UTC, and java.time certainly has classes for that (`Instant`, `OffsetDateTime` with `ZoneOffset.UTC`). – Basil Bourque Jan 17 '17 at 15:43