ike3
ike3

Reputation: 1800

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?

Upvotes: 16

Views: 40839

Answers (6)

Thibaut Mottet
Thibaut Mottet

Reputation: 414

If you use the Spring Framework you can use the @JsonSerialize and @JsonDeserialize annotations. It will parse correctly your javascript Date.

Example:

public class product {

    @NotNull
    private Long id;
    
    @NotNull
    private String name;

    @JsonSerialize(using = CustomLocalDateSerializer.class)
    @JsonDeserialize(using = ISO8601LocalDateDeserializer.class)
    private LocalDate date;

    // getter and setter...
}

Upvotes: 1

Camille Vienot
Camille Vienot

Reputation: 807

This thread is rather old. Nowadays, with java 8, you should use ZonedDateTime in your form dto. Using spring-mvc, Jackson will properly map a ISO format (ex: "2019-03-27T22:05:42.763Z") to a ZonedDateTime.

However the method Date.toISOString always set the timezone to utc, so your deserialized ZonedDateTime zone will always be set to UTC. It can be a issue if you need the zone on the server side. Let's say for example you need to send to a customer an email with a date he/she just submitted through a form: you want to use the same zone.

If you want to pass the timezone and comply to the ISO format, you should use a lib like moment.js to format dates in javascript. And then when serializing :

moment().format('YYYY:MM:DDTHH:mm:ssZ') // "2019:03:27T23:06:11+01:00"

Upvotes: 1

Nils
Nils

Reputation: 1750

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);

Upvotes: 15

Bruno
Bruno

Reputation: 122749

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")).

Upvotes: 14

Pablo Grisafi
Pablo Grisafi

Reputation: 5047

JSON does not have Date support, all parser/serializers use the toString or something like that. It is up to you to serialize/deserialize dates.
Since Javascript do not have a decent date formatter included, the simplest solution is to transform date to long. But if you want to be able to read what is going on, I recommend http://www.datejs.com/ and formatting dates as yyyy-MM-dd HH:mm:ss

Upvotes: 0

Victor Stafusa
Victor Stafusa

Reputation: 14623

I personally would convert them to String in java using something like this:

String theDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);

And then the String is serialized. In the javascript side you, just parse that.

Upvotes: 0

Related Questions