Jackson @JsonFormat 将日期设置为少一天
Jackson @JsonFormat set date with one day less
我已经在我的项目中使用 Spring Date Rest with Spring Boot。
这个项目有一个对象,我使用了注释@JsonFormat 来格式化将从我的 Json 接收的日期字段。
字段 Date 的格式为 "dd/MM/yyyy"。
当我发送 json 值“08/07/1980”时,Jackson 将其转换为值“07/07/1980”。
问题是@Json格式设置的日期少了一天
这是我的源代码
@Temporal(TemporalType.DATE)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "UTC")
private Date birthDate;
谢谢
使用这个解决方案,它比我的解决方案更有效、更现代:
谢谢@Benjamin Lucidarme。
我使用以下方法解决了我的问题:
@Temporal(TemporalType.DATE)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "Brazil/East")
private Date birthDate;
我将时区更改为 "Brazil/East" 或 "America/Sao_Paulo",现在正在工作
谢谢
@William 的回答有效,但您应该将这些行添加到您的 application.properties 文件中:
spring.jackson.time-zone=Brazil/East
spring.jackson.locale=pt-BR
这样,您只需填写一次时区和地区,它适用于您申请的所有日期。
我会将 ObjectMapper
时区设置为默认 JVM 时区:
ObjectMapper objectMapper = new ObjectMapper();
//Set default time zone as JVM timezone due to one day difference between original date and formatted date.
objectMapper.setTimeZone(TimeZone.getDefault());
如果您不知道服务器环境使用的时区,这是一个更好的解决方案。
在 spring-boot
环境中,您可以覆盖默认值 JacksonAutoConfiguration
:
@Bean
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.createXmlMapper(false)
// Set timezone for JSON serialization as system timezone
.timeZone(TimeZone.getDefault())
.build();
}
在双方(客户端 - 服务器)上注释您的归档日期:
@JsonDeserialize(using = JsonDateDeserializer.class)
@JsonSerialize(using = JsonDateSerializer.class)
private Date birthDate;
并且在两侧再次放置用于序列化和反序列化的实现:
public class JsonDateSerializer extends JsonSerializer<Date> {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
@Override
public void serialize(final Date date, final JsonGenerator gen, final SerializerProvider provider) throws IOException, JsonProcessingException {
String dateString = format.format(date);
gen.writeString(dateString);
}
}
public class JsonDateDeserializer extends JsonDeserializer<Date> {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
@Override
public Date deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (jp.getCurrentToken().equals(JsonToken.VALUE_STRING)) {
try {
Date date = format.parse(jp.getText().toString());
return date;
} catch (ParseException e) {
//e.printStackTrace();
}
}
return null;
}
}
我也遇到过类似的问题。我想为这个问题添加的所有答案都是针对上述问题的,我的解决方案将解释问题并提供通用解决方案。
当您对同一个 Date
使用 2 个不同的时区时,您可能会遇到这个问题。
当您执行 new Date()
时,除非您明确指定时区,否则它会使用您的默认时区。让我用代码片段向您解释一下,(您在印度,当前日期是 (9/5/2021, 12 a.m.IST)
// 09/05/2021 00:00:00 IST
Date birthDate = new Date();
现在,当在 birthDate
上方设置模型并使用 JsonFormat 序列化时。默认情况下 JsonFormat 使用 UTC 时区。
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
private Date birthDate;
序列化将导致 08/05/2021
,而不是 09/05/2021
。
让我写下 08/05/2021 UTC
和 09/05/2021 IST
时区的日期。
让我也为日期 08/05/2021 18:30:00 UTC
和 09/05/2021 00:00:00 IST
添加时间。
如果您看到日期正确,但时区不同,现在您明白了为什么会这样。有两种方法可以解决这个问题,
- 使用相同的时区
- 在序列化日期时也添加时间和时区。喜欢
08/05/2021 18:30:00 UTC
,和 09/05/2021 00:00:00 IST
我已经在我的项目中使用 Spring Date Rest with Spring Boot。 这个项目有一个对象,我使用了注释@JsonFormat 来格式化将从我的 Json 接收的日期字段。 字段 Date 的格式为 "dd/MM/yyyy"。 当我发送 json 值“08/07/1980”时,Jackson 将其转换为值“07/07/1980”。
问题是@Json格式设置的日期少了一天
这是我的源代码
@Temporal(TemporalType.DATE)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "UTC")
private Date birthDate;
谢谢
使用这个解决方案,它比我的解决方案更有效、更现代:
谢谢@Benjamin Lucidarme。
我使用以下方法解决了我的问题:
@Temporal(TemporalType.DATE)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy", locale = "pt-BR", timezone = "Brazil/East")
private Date birthDate;
我将时区更改为 "Brazil/East" 或 "America/Sao_Paulo",现在正在工作
谢谢
@William 的回答有效,但您应该将这些行添加到您的 application.properties 文件中:
spring.jackson.time-zone=Brazil/East
spring.jackson.locale=pt-BR
这样,您只需填写一次时区和地区,它适用于您申请的所有日期。
我会将 ObjectMapper
时区设置为默认 JVM 时区:
ObjectMapper objectMapper = new ObjectMapper();
//Set default time zone as JVM timezone due to one day difference between original date and formatted date.
objectMapper.setTimeZone(TimeZone.getDefault());
如果您不知道服务器环境使用的时区,这是一个更好的解决方案。
在 spring-boot
环境中,您可以覆盖默认值 JacksonAutoConfiguration
:
@Bean
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.createXmlMapper(false)
// Set timezone for JSON serialization as system timezone
.timeZone(TimeZone.getDefault())
.build();
}
在双方(客户端 - 服务器)上注释您的归档日期:
@JsonDeserialize(using = JsonDateDeserializer.class)
@JsonSerialize(using = JsonDateSerializer.class)
private Date birthDate;
并且在两侧再次放置用于序列化和反序列化的实现:
public class JsonDateSerializer extends JsonSerializer<Date> {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
@Override
public void serialize(final Date date, final JsonGenerator gen, final SerializerProvider provider) throws IOException, JsonProcessingException {
String dateString = format.format(date);
gen.writeString(dateString);
}
}
public class JsonDateDeserializer extends JsonDeserializer<Date> {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
@Override
public Date deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (jp.getCurrentToken().equals(JsonToken.VALUE_STRING)) {
try {
Date date = format.parse(jp.getText().toString());
return date;
} catch (ParseException e) {
//e.printStackTrace();
}
}
return null;
}
}
我也遇到过类似的问题。我想为这个问题添加的所有答案都是针对上述问题的,我的解决方案将解释问题并提供通用解决方案。
当您对同一个 Date
使用 2 个不同的时区时,您可能会遇到这个问题。
当您执行 new Date()
时,除非您明确指定时区,否则它会使用您的默认时区。让我用代码片段向您解释一下,(您在印度,当前日期是 (9/5/2021, 12 a.m.IST)
// 09/05/2021 00:00:00 IST
Date birthDate = new Date();
现在,当在 birthDate
上方设置模型并使用 JsonFormat 序列化时。默认情况下 JsonFormat 使用 UTC 时区。
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
private Date birthDate;
序列化将导致 08/05/2021
,而不是 09/05/2021
。
让我写下 08/05/2021 UTC
和 09/05/2021 IST
时区的日期。
让我也为日期 08/05/2021 18:30:00 UTC
和 09/05/2021 00:00:00 IST
添加时间。
如果您看到日期正确,但时区不同,现在您明白了为什么会这样。有两种方法可以解决这个问题,
- 使用相同的时区
- 在序列化日期时也添加时间和时区。喜欢
08/05/2021 18:30:00 UTC
,和09/05/2021 00:00:00 IST