Spring @DateTimeFormat is changing timezone while converting @PathVariable to Date

时间:2016-10-04 14:45:27

标签: java spring rest spring-mvc datetime-format

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?

3 个答案:

答案 0 :(得分:2)

问题原因可能是时区,java.util.Date即时时间被转换回东部时区,因此您可以看到该值。如果您使用的是Java 8,LocalDate应该为您解决问题。

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

以下为您发布一些选项

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

答案 1 :(得分:1)

Nhu Vy的answer指向了正确的方向;但我没有添加时区信息,而是将其删除。

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

从配置中删除此内容并单独保留默认时区。这对我有用。

答案 2 :(得分:0)

我遇到了同样的问题,我只在我的Serializer文件中添加了UTC。我的意思是,而不是:

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

我用过:

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

这是完整的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');
    }

}

此代码摘自Serializing Joda DateTime with Jackson and Spring

希望它有所帮助。