Javascript and Java Date JSON serialization

36,587

Solution 1

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

Solution 2

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

Solution 3

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...
}
Share:
36,587
ike3
Author by

ike3

Updated on December 23, 2020

Comments

  • ike3
    ike3 over 3 years

    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?

  • Pointy
    Pointy over 12 years
    I think the issue is going from JavaScript to Java.
  • Zlatko
    Zlatko over 12 years
    Or the other way around: stringify in Javascript to parse in Java, as the author wants Javascript-> Java, if I read the question correctly.
  • ike3
    ike3 over 12 years
    Yes, I am thinking about writing custom Date serializer/deserializer for Spring MVC+Jackson.
  • ike3
    ike3 over 12 years
    I did some more research and found that epoch is treated differently in java and javascript (stackoverflow.com/questions/8913059/…). If I cannot rely on getTime() method I have no idea how to use epoch time.
  • Bruno
    Bruno over 12 years
    They only behave differently in the way they tie the time zone to your location at the time. I thought your input were (correct) JS Date instances in the first place? How do you build them? Can you show an example of how you produced 5 Jan 1975 initially?
  • ike3
    ike3 over 12 years
    I am getting Date from jQuery DatePicker $("date").datePicker("getTime") when 5 Jan 1975 is choosen in the calendar. Then it is serialized to JSON using JSON.stringify, which uses 4 hours difference independent on the year. But Java knows that before 2011 it was GMT+3 and deserializes it in the correct way so I get 1 hour difference for dates before 2011
  • Chanandler Bong
    Chanandler Bong over 8 years
    Another advantage is an easy comparison - you don't need to deserialise to compare the dates.
  • anhquan
    anhquan about 4 years
    I am again your idea because transfering the long string like 'yyyy-MM-dd'T'HH:mm:ss.SSSXXX' is not so effective like just a number epoch.