5

I'm trying to use spring's automatic String to Date conversion when getting date as @PathVariable using @DateTimeFormat. The automatic conversion is done, but for some reason the date is converted to the date I passed minus four hours (Easter Daylight Time, where the server and client are both located).

Example:

URL: .../something/04-10-2016/somename Will result someDate object with value 2016/10/03 20:00:00 (i.e. 8 PM of the previous day, which is 4 hours behind the date I passed.)

How do I avoid this auto timezone conversion. I don't need any timezone information, and this conversion is breaking the behavior I expected.

Here's my code:

@RequestMapping(value = "/something/{someDate}/{name}", method = RequestMethod.GET, headers = "Accept=application/json")
@ResponseBody
public SomeObject getDetails(@PathVariable @DateTimeFormat(pattern = "dd-MM-yyyy") Date someDate,
    @PathVariable String name) {
    // date here comes as GMT - 4
    // more code here
    // return someObject;
}

For I now, I'm working around this by just reading the path variable as a String and using SimpleDateFormatter to convert the String to Date manually.

Any idea on how I can get the auto conversion work without timezone conversion?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
Suraj Bajaj
  • 6,630
  • 5
  • 34
  • 49

3 Answers3

5

Cause of issue is probably the timezone, java.util.Date instant time is converted back into Eastern Time zone hence you see the value. If you are using Java 8, LocalDate should solve the problem for you.

@PathVariable @DateTimeFormat(pattern = "dd-MM-yyyy") LocalDate date

Following post some options for you neatly

https://www.petrikainulainen.net/programming/spring-framework/spring-from-the-trenches-parsing-date-and-time-information-from-a-request-parameter/

Arthur
  • 1,332
  • 2
  • 19
  • 39
kuhajeyan
  • 10,727
  • 10
  • 46
  • 71
  • 1
    I haven't tried this; but even if it worked, I'd still have to convert `LocalDate` to `Date`, as the API that I'm using takes Date object. This is almost as good as using `SimpleDateFormatter`. – Suraj Bajaj Oct 04 '16 at 18:07
1

Do Nhu Vy's answer pointed in the right direction; but instead of adding the timezone information, I had to remove it.

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

Removed this from the config and left the default timezone alone. This worked for me.

Community
  • 1
  • 1
Suraj Bajaj
  • 6,630
  • 5
  • 34
  • 49
0

I've got the same problem and I only add the UTC in my Serializer file. What I mean, instead of:

private static final DateTimeFormatter FORMATTER = ISODateTimeFormat.dateHourMinute();

I used:

private static final DateTimeFormatter FORMATTER = ISODateTimeFormat.dateHourMinute().withZoneUTC();

This is the final code of the full JsonJodaDateTimeSerializer.java:

package cat.meteo.radiosondatge.commons;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

/**
 * When passing JSON around, it's good to use a standard text representation of
 * the date, rather than the full details of a Joda DateTime object. Therefore,
 * this will serialize the value to the ISO-8601 standard:
 * <pre>yyyy-MM-dd'T'HH:mm:ss.SSSZ</pre> This can then be parsed by a JavaScript
 * library such as moment.js.
 */
public class JsonJodaDateTimeSerializer extends JsonSerializer<DateTime> {

    private static final DateTimeFormatter FORMATTER = ISODateTimeFormat.dateHourMinute().withZoneUTC();

    @Override
    public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2)
            throws IOException, JsonProcessingException {

        gen.writeString(FORMATTER.print(value) + 'Z');
    }

}

This code was extracted from Serializing Joda DateTime with Jackson and Spring

Hope it helps.

Community
  • 1
  • 1