Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript and Java Date JSON serialization

I have an javascript object with Date property which is being converted to JSON using JSON.stringify

I am on GMT+4 time zone (Russia/Moscow)

For example, 5 Jan 2012 converts to 2012-01-04T20:00:00.000Z

5 Jan 1975 converts to 1975-01-04T20:00:00.000Z

But in 1975 it was GMT+3 time zone, as daylight saving was canceled in Russia in 2011. So when it cames to server (java) it deserializes as:

2012-01-04T20:00:00.000Z becames 5 Jan 2012 00:00 - OK

1975-01-04T20:00:00.000Z becames 4 Jan 1975 23:00 - WRONG!

What is the recommended way to convert Date object to JSON in Javascript?

like image 731
ike3 Avatar asked Jan 18 '12 13:01

ike3


People also ask

Is date serializable JavaScript?

Dates are encoded as ISO 8601 strings and then treated just like a regular string when the JSON is serialized and deserialized. You can serialize to this format, but there's no direct deserialization back to a date from it.

What is Java JSON serialization?

JSON-Java is a Java serialization/deserialization library. It parses JSON documents into Java objects and generates new JSON documents from the Java classes.

Is date supported in JSON?

JSON does not have a built-in type for date/time values. The general consensus is to store the date/time value as a string in ISO 8601 format.

Are date objects serializable?

stringify serializes your object, it turns the date into a string. This is how you usually serialize date objects in any language. There are well-known formats for date objects, which specify how a date should look when it is turned into a string.


2 Answers

I prefer to stick to javascripts ISO 8601 date format, when parsing it correctly it'll will automatically handle timezone differences.

In java you can parse a javascript Stringified JSON date as follows:

String iso8601Date = "2013-08-13T14:15:00.000Z";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date parsedDate = formatter.parse(iso8601Date);

When turning it back into strings, you'll have something like this

//"2013-08-13T16:15:00.000+02:00"
String formattedDate = formatter.format(parsedDate);

For parsing JSON I use FlexJson, which you can configure like this.

//Serializing to JSON
DateTransformer dateTransformer = new DateTransformer("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
new JSONSerializer().transform(dateTransformer, Date.class).serialize(object);
//deserialize From JSON (replace object by java class)
JSONDeserializer<..Object..>().use(Date.class, dateTransformer).deserialize(json);
like image 117
Nils Avatar answered Oct 10 '22 12:10

Nils


I would suggest passing the date/times around using their seconds since epoch notation, more specifically the number of seconds since the Unix Epoch (1 Jan 1970 00:00 GMT). If you're not familiar with this, there is an example converter here: http://www.epochconverter.com/

This has a few advantages:

  • It refers to the same moment in time independently of the time zone. This helps storing the time independently of time zone errors (although they would have to be input correctly in the first place, of course).
  • It's the only non-deprecated constructor (except constructor without params) in java.util.Date, see (getTime() too). (Note that this uses milliseconds.)
  • JavaScript can build date from it quite easily (e.g. new Date(1000 * 1326894706)). (Note that this uses milliseconds.)
  • If it matters, it's always going to be a bit smaller (in terms of data size in its JSON serialization) than any of "yyyy-MM-dd HH:mm:ss".
  • If you want the time zone to be rendered and associated with this number, you could always add an extra field to your representation. { "datetime": 1326894706, "tz": "GMT" } is still shorter than { "datetime": "18 Jan 2012 13:51:46 GMT" }.

Considering it's easy to get Date instances from this in Java and JavaScript, you can then use a DateFormatter to convert it to/from text in Java. For JavaScript, using a library such as Date Format will help you render it as appropriate on the page (for example with something like new Date(val * 1000).format("yyyy-mm-dd HH:MM")).

like image 21
Bruno Avatar answered Oct 10 '22 12:10

Bruno