I\'m receiving a JSON object with date value like this:
{\"PostingDate\":\"\\/Date(1325134800000-0500)\\/\"}
And I want to parse it in Java
In Java >= 8 you can use the new java.time API.
The input contains:
1325134800000), which is the number of milliseconds since unix epoch (1970-01-01T00:00Z)-0500), which is the difference from UTC (in this case, 5 hours behind UTC)In the new java.time API, there are lots of different types of date/time objects. In this case, we can choose to use a java.time.Instant (which represent a count of nanoseconds since unix epoch) or a java.time.OffsetDateTime (which represents the Instant converted to a date/time in a specific offset).
To parse the String, I use a java.time.format.DateTimeFormatterBuilder to create a java.time.format.DateTimeFormatter. I also use a java.time.temporal.ChronoField to specify which fields I'm parsing:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// epoch seconds
.appendValue(ChronoField.INSTANT_SECONDS)
// milliseconds
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
// offset
.appendPattern("xx")
// create formatter
.toFormatter();
I also use a regex to extract just the relevant part from the input String (although you could also use substring() to get it):
String s = "/Date(1325134800000-0500)/";
// get just the "1325134800000-0500" part - you can also do s.substring(6, 24)
s = s.replaceAll(".*/Date\\(([\\d\\+\\-]+)\\)/.*", "$1");
Then I can parse to the type I want:
// parse to Instant
Instant instant = Instant.from(fmt.parse(s));
// parse to OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(s, fmt);
The Instant is equivalent to 2011-12-29T05:00:00Z (Instant is just a point in the timeline, and you can think that's always in UTC).
The OffsetDateTime has the same instant, but converted to -0500 offset, so its value is 2011-12-29T00:00-05:00. But both Instant and OffsetDateTime represents the same point in time.
To convert to java.util.Date, use the Instant:
// convert to java.util.Date
Date date = Date.from(instant);
// if you have an OffsetDateTime, you can do this:
Date date = Date.from(odt.toInstant());
That's because the java.util.Date has no timezone/offset information and it just represents the count of milliseconds since unix epoch (the same concept of Instant), so it can be easily converted from an Instant.
For Java 6 and 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it here).
The difference from Java 8 is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same. So the formatter creation and the parsing code to Instant and OffsetDateTime are the same.
Another difference is that, in Java <= 7, the java.util.Date class has no from() method. But you can use the org.threeten.bp.DateTimeUtils class to do the conversion:
// convert to java.util.Date
Date date = DateTimeUtils.toDate(instant);
// or from the OffsetDateTime
Date date = DateTimeUtils.toDate(odt.toInstant());