Milan Nosáľ
Milan Nosáľ

Reputation: 19737

Unmarshalling JSON to Groovy in Grails Date

I am working Grails 2.4 and Ajax. On the client I build JSON data as follows:

var data = {
    // ... not important
    date: new Date(
            parseInt($("#date_year").val()),
            parseInt($("#date_month").val()) - 1,
            parseInt($("#date_day").val())),
    // ...
};

I send the date with jQuery Ajax:

$.ajax({
    url: '${createLink(controller: 'report', action: 'save')}',
    type: 'POST',
    data: JSON.stringify(data),
    contentType: 'application/json; charset=utf-8',
    success: function (respondData, textStatus, jqXHR) {
        alert('Saved succesfully');
    },
    error: function(jqXHR, textStatus, errorThrown) {
        alert('NOT SAVED!!!');
    }
});

In the report controller ReportController I have action save(ThreatReport report). By some magic, Grails is able to unmarshall the JSON data to Groovy model represented by ThreatReport report argument (if anyone would point me to some documentation about how is this configured I would be much obliged). ThreatReport class has a Date attribute (and other, but they are working fine). However, Grails seem to have troubles converting this date. In JavaScript I got

Wed Jun 10 2015 00:00:00 GMT+0200 (Central Europe Daylight Time)

however, in the Groovy controller it is suddenly a day back:

Tue Jun 09 00:00:00 CEST 2015

As I stated, the rest of attributes are converted correctly.

Upvotes: 0

Views: 471

Answers (2)

Milan Nosáľ
Milan Nosáľ

Reputation: 19737

OK, so finally I got a solution. It is connected to timezones. However, the problem seems to be in a combination of a browser + my configuration of Grails. Browser serializes the date to a string in the zulu timezone, that means that after creating a date in my timezone (+02:00) e.g., 13. May 1999 00:00:00 it will get serialized to 12. May 1999 22:00:00. However, the Grails was set to parse only the date and not the time, so in the end I got 12. May 1999 00:00:00 on the serverside. Then it seemed like a 24 hours shift. Now I use my own simple code to serialize it directly to the proper ISO date:

var data = {
    // ... not important
    date: $("#date_year").val() + "-" + $("#date_month").val() + "-" + $("#date_day").val(),
    // ...
};

So it will become a string "1999-5-13".

Upvotes: 0

Gunnar
Gunnar

Reputation: 413

I've had timezone issues in Java before, have you allready tried -Duser.timezone as an argument for your JVM startup?

See http://en.wikipedia.org/wiki/List_of_tz_database_time_zones

Example:

...java -Duser.timezone=Europe/London

Or (not sure if this works)

...java -Duser.timezone=Etc/GMT+2

Update

The java test code

Date date = new Date("2015/6/10");
System.out.println(date);
DateTime date2 = new DateTime(date.getTime(), DateTimeZone.UTC);
System.out.println(date2);

produces the output

Wed Jun 10 00:00:00 CEST 2015
2015-06-09T22:00:00.000Z

as an example for day switching problems because of timezone and/or DST Problems (in my case the testing JVM works with my correct timezone GMT+2, so I forced UTC in the second date with the timestamp from the first date).

Maybe this is not your specific problem, but maybe it helps when you pass the correct timezone as a parameter to the JVM of your web application server (for example in a tomcat startup script, not in your IDE). Try for example "Etc/GMT+2", when you're in Europe with daylight saving.

This must not but could be the root of your problem, I'm not familar with the frameworks you use but I know timezone and daylight saving problems can be complex/confusing, because it can be a mashup of custom and default settings (OS, JVM) and how frameworks deal with dates with/without times and/or timezones.

In case it helps don't forget to adjust JVM calls on other systems for your application regarding the timezone parameter :-)

Upvotes: 1

Related Questions