I'm receiving a JSON object with date value like this:
{"PostingDate":"\/Date(1325134800000-0500)\/"}
And I want to parse it in Java code to Date
or getting it as a String
.
I want to know what is the easy way of doing it.
I'm receiving a JSON object with date value like this:
{"PostingDate":"\/Date(1325134800000-0500)\/"}
And I want to parse it in Java code to Date
or getting it as a String
.
I want to know what is the easy way of doing it.
I take it the first number (1325134800000
) is the number of milliseconds since epoch, and -0500
is the time zone. This appears to be the case given the sample code below, which seems to do what you want.
The following code parses the JSON input using Jackson, which I recommend if you don't have a JSON parsing library of choice yet. It lacks error checking etc.
Sample code:
public final class Foo
{
public static void main(final String... args)
throws IOException
{
// What the JSON value must match exactly
// Not anchored since it will be used with the (misnamed) .matches() method
final Pattern pattern
= Pattern.compile("\\\\/Date\\((\\d+)(-\\d+)?\\)\\\\/");
final ObjectMapper mapper = new ObjectMapper();
// Parse JSON...
final JsonNode node = mapper.readTree(
"{\"PostingDate\": \"\\/Date(1325134800000-0500)\\/\"}");
if (!node.has("PostingDate")) {
System.err.println("Bad JSON input!");
System.exit(1);
}
// Get relevant field
final String dateSpec = node.get("PostingDate").getTextValue();
// Try and match the input.
final Matcher matcher = pattern.matcher(dateSpec);
if (!matcher.matches()) {
System.err.println("Bad pattern!"); // Yuck
System.exit(1);
}
// The first group capture the milliseconds, the second one the time zone
final long millis = Long.parseLong(matcher.group(1));
String tz = matcher.group(2);
if (tz.isEmpty()) // It can happen, in which case the default is assumed to be...
tz = "+0000";
// Instantiate a date object...
final Date date = new Date(millis);
// And print it using an appropriate date format
System.out.printf("Date: %s %s\n",
new SimpleDateFormat("yyyy/MM/dd HH:MM:ss").format(date), tz);
}
}
Output:
Date: 2011/12/29 06:12:00 -0500
Hier is a working parsing method based on the version of fge but improved as
=>
private static final Pattern bingTimePattern = Pattern.compile("\\/Date\\((\\d+)([-+]\\d+)?\\)\\/");
public static DateTime parseBingTime(String timeAsString) throws ParseException {
Matcher matcher = bingTimePattern.matcher(timeAsString);
if (!matcher.find())
throw new ParseException("wrong date time format " + timeAsString, 0);
final long millis = Long.parseLong(matcher.group(1));
String tz = matcher.group(2);
if (tz.isEmpty())
tz = "+0000";
return new DateTime(millis, DateTimeZone.forID(tz));
}
I have created a simple JavaScript function using Jquery DatePicker
function JsonToJSDate(jsonDate) { var reg = /-?\d+/; var m = reg.exec(jsonDate); return new Date(parseInt(m[0])); }
$('#Started').val($.datepicker.formatDate('mm/dd/yy', JsonToJSDate(yourDateVarHere)));
Simple thing but handling my job.
Extract your object value from JSON and apply substring.
e.g:
String postingDateObjectValue = "\\/Date(1442436473422)\\/";
String dateStringInMillis = postingDateObjectValue .substring(7,20);
now parse millis and use them where ever you want.
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());