SpringBoot中关于日期时间时区的问题

SpringBoot中关于日期时间时区的问题

  1. 首先需要知道的是,每个时区的时间毫秒数都是相同的,只是在不同的时区使用不同的表示而已。
  2. 在Java中,Date对象存储的是自1970年1月1日00:00:00 GMT以来的毫秒数,它本身并不包含时区信息,而是以UTC时间存储。
  3. 如果前端传过来了日期参数,后端使用Date对象接收,这属于是使用jackson将字符串反序列化为对象。需要根据参数中是否携带了时区信息来分别看待。
    • 如果参数中没有携带时区信息 传递的日期格式为:yyyy-MM-dd HH:mm:ss,传递的值为2024-01-01 00:00:00,那么后端通过断点查看到的日期就是2024-01-01 08:00:00。这主要是因为时区的问题,jackson接收到日期参数之后,将2024-01-01 00:00:00转换为毫秒,认为这个毫秒代表的是0时区的时间(spring.jackson.time-zone的默认时区配置就是0时区),装载给Date对象。我们在后端通过断点查看Date的值的时候,因为服务器的默认时区是GMT+8(东八区),所以Date根据服务器默认时区将原本装载的0时区转换一下,变成相同毫秒数的东八区时间。
    • 如果参数中携带了时区信息,传递的参数类似于:2024-01-01T00:00:00.041+08:00,这代表是东八区的日期时间。那么后端通过断点查看到的值就是2024-01-01 00:00:00jackson接收到日期参数之后,发现参数带着时区信息,时区为东八区。那么jackson会认为这个时间代表的就是东八区的时间,将东八区的时间2024-01-01 00:00:00转换成0时区2023-12-31 04:00:00,然后装载到Date对象中。我们在后端通过断点查看Date的值的时候,因为服务器的默认时区是GMT+8(东八区),所以Date根据服务器默认时区将原本装载的0时区转换一下,变成相同毫秒数的东八区时间。
    • 如果后端是有的是LocalDateTime接收的参数,则不需要考虑时区的问题,前端传的是什么时间,就是你服务器时区的什么时间,也就是说LocalDateTime是没有时区概念的。
  4. 如果后端返回了日期参数,这属于是jackson序列化对象为字符串。前端接收到的日期可能会和后端不一致,这主要也是时区的问题。
    • 如果后端返回的对象是Date类型,jackson按照spring.jackson.time-zone的配置,在序列化的时候按照0时区进行转换。如果服务器是东八区jackson会在东八区时间的基础上减少8个小时,得到此时此刻0时区的时间,然后返回给前端。
    • 如果将spring.jackson.time-zone参数设置为东八区,那么jackson在序列化的时候就会按照东八区进行转换。如果服务器是东八区,序列化之后并返回给前端的日期不发生改变。
    • 如果返回的对象是LocalDateTime,则不需要关心时区,返回的就是服务器的本地时间(LocalDateTime.now())。

posted on 2024-04-09 08:30  zhaoLei_Free  阅读(590)  评论(0编辑  收藏  举报

导航