【问题标题】:lost one day for a date失去了一天的约会
【发布时间】:2015-10-15 19:38:23
【问题描述】:

在客户端,我使用 dd/MM/yyyy 日期格式。该字段使用 twitter bootstrap 3 日期时间选择器 (https://eonasdan.github.io/bootstrap-datetimepicker/)

我通过 twitter bootstrap 3 日期时间选择器输入 24/07/2015
在我发送的 json 中,我看到:生日:“24/07/2015”

在我的 dto 中,我愿意

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
private Date birthdate;

当我在服务器上收到日期时,在我的 d 中看到:23/07/2015 19:00

一天过去了。

有什么解释吗?

【问题讨论】:

  • 您是否检查过系统上的当地时间设置?
  • 客户端/服务器在同一台机器上:两者都是 edt -4 小时(mtl 时间)...
  • 绝对是时区转换问题。一方面将时间视为UTC,另一方面将转换为本地时间。我们在与第 3 方系统的某些客户端/服务器集成中遇到了这个问题。死的赠品是加到其他时间的“19:00”,正好是5个小时的时差(实际上不是一整天)。
  • 浏览器端我得到了一个新日期:2015 年 7 月 24 日星期五 23:49:26 GMT-0400 (EDT)。在我得到的服务器上:Fri Jul 23:49:26 EDT 2015. 我认为东部夏令时 (EDT) = GMT-4 (USA + Canada)
  • 如果您使用 Postman 等工具查询您的服务,日期是否不正确?就我而言,问题出在 restTemplate 客户端,而不是在服务器中。

标签: java json jackson orika spring-restcontroller


【解决方案1】:

我在 java 中遇到了同样的问题。您可以使用 ObjectMapper 设置为默认时区

ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
mapper.setTimeZone(TimeZone.getDefault());

这里的解决方案:Jackson @JsonFormat set date with one day less

完整的配置类:

@Configuration
@EnableWebMvc
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    for (HttpMessageConverter converter : converters) {
        if (converter instanceof org.springframework.http.converter.json.MappingJackson2HttpMessageConverter) {
            ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
            mapper.registerModule(new Hibernate5Module());
            mapper.setTimeZone(TimeZone.getDefault());
        }
    }
}

【讨论】:

    【解决方案2】:

    从日期选择器中选择日期时,我在 JavaScript 中遇到了同样的问题。我使用 .toString() 方法格式化了字段,但该函数给了我一个不同的日期(我也搞砸了一天)。像这样:

    var mydate = new Date('2020-04-03'); console.log(mydate.toString());

    //Thu Apr 02 2020 20:00:00 GMT-0400 (Eastern Daylight Time)

    我改用 .toUTCString() 修复它。

    var mydate = new Date('2020-04-03');
    
    console.log(mydate.toUTCString());
    
    //Fri, 03 Apr 2020 00:00:00 GMT
    

    【讨论】:

      【解决方案3】:

      有同样的问题。使用邮递员验证客户端不是罪魁祸首。似乎杰克逊使用的时区与系统的时区存在问题。不得不更改 Jackson 配置以补偿日期

      @Configuration
      
      public class JacksonConfig {
      
          @Bean
          @Primary
          public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
              final Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder();
              jackson2ObjectMapperBuilder.timeZone(TimeZone.getDefault());
              jackson2ObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
              jackson2ObjectMapperBuilder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
              return jackson2ObjectMapperBuilder;
          }
      
      }
      

      【讨论】:

        【解决方案4】:

        AimZ 的答案是我指出这一点的原因,但我将这三行添加到我的 application.properties 文件中并实现了同样的效果

        spring.jackson.date-format=yyyy-MM-dd

        spring.jackson.serialization.write-dates-as-timestamps:false

        spring.jackson.time-zone:EST

        【讨论】:

          【解决方案5】:

          根据JacksonFAQDateHandling页面:

          与 TimeZone (java.util.Calendar) 关联的所有时间对象 等)杰克逊构造使用标准时区(GMT),不是 本地时区(无论是什么)。即:杰克逊默认为 使用 GMT 进行所有处理除非另有明确说明。

          在您的情况下,日期似乎已自动转换为 GMT/UTC。尝试明确提供您的本地时区以避免 UTC 转换 [如问题中所述这个时间怎么会相差 9 小时? (5 小时、3 小时等) 在同一页]:

          @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd/MM/yyyy", timezone="EST")
          

          其次,我认为您正在使用Date.toString() 打印日期。 Note java Date 类与时区无关,但其toString() 方法在打印前使用系统的默认时区。

          这里看起来24/07/2015 00:00 UTC 正在被toString() 转换为23/07/2015 19:00 EST。这两个都代表相同的时刻时间,但在不同的时区。

          【讨论】:

          • 我不使用 toString(),但是当@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy") 时,可能会调用 toString。有没有标准的解决方案来管理这个?只保留 gmt 日期...但需要知道某处用户的时区才能正确显示日期。也许某些东西可以与 java 8 或 joda 的新日期一起使用?
          • 最佳实践是将日期/时间信息以 UTC 格式存储在数据库中,并存储用户的时区。然后在向用户显示日期时使用该时区或在存储前删除时区偏移量。有很多文章列出了这种方法的好处,即应用程序可以支持不同的时区。 Java8 Date API 提供了一组新的类来处理日期/时间。这是一篇关于 Java8 Date API dzone.com/articles/deeper-look-java-8-date-and 的好文章。 Java8 或 Joda 简化了日期/时区处理。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-22
          • 2020-06-02
          • 1970-01-01
          • 2013-03-07
          • 2013-01-24
          • 2015-07-08
          • 1970-01-01
          相关资源
          最近更新 更多