当前位置: 代码迷 >> 综合 >> @DateTimeFormat 和 @JsonFormat 的详细研究,以及timezone=“GMT+8“的研究,时区问题(1)
  详细解决方案

@DateTimeFormat 和 @JsonFormat 的详细研究,以及timezone=“GMT+8“的研究,时区问题(1)

热度:27   发布时间:2023-12-16 05:57:17.0

注意:以下所有的内容,是通过实验得出,并进行总结,如有错误,请指正

0 前置知识

CST是什么

  • 后续的0时区,就是中时区,就是国际时间,就是UTC+0;中国的CST是UTC+8,美国的CST是UTC-6。
  • 详解 GMT和UTC

1 @DateTimeFormat

注意:url拼接的参数才生效

1.1 正确用法:

1.1.1 例如:

  • 请求URL : http://localhost:9999/put?date=2020-03-07 13:13:13

  • 后端代码

@PostMapping("put")
public User put(@DateTimeFormat(pattern = "yyyy-MM-dd HH") @RequestParam Date  date){
    System.out.println(date); // Sat Mar 07 13:00:00 CST 2020 // 可以看到分和秒都被忽略了。
}

1.2 错误用法

  • 放在请求体或者表单
class User{
    @DateTimeFormat(pattern = "yyyy-MM-dd")  // 这样没有作用private Date date;/*getter setter*/
}

1.3 总结:

	@DateTimeFormat 的作用只是将路径请求参数的字符串转成想要格式的Date对象。

2. @JsonFormat

注意:

  1. 不可用于url的路径参数。也就是说像@DateTimeFormat那样用不可以。
  2. timezone解释:
    意思是用于序列化时,指定这个默认时区,也就是传进来的字符串的时区。默认是UTC就是:0时区。(因为服务器也有一个时区,所以要根据传进值的时区,进行转换,后续详细演示)
    源码注释:
/*** {@link java.util.TimeZone} to use for serialization (if needed).* Special value of {@link #DEFAULT_TIMEZONE}* can be used to mean "just use the default", where default is specified* by the serialization context, which in turn defaults to system* default (UTC) unless explicitly set to another timezone.*/
public String timezone() default DEFAULT_TIMEZONE;

2.1 正确用法1,输入

2.1.1 未指定timezone

  • web服务器实体bean
class User{
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") // 这里未指明 传入字符串的时区private Date date;
}
  • 前台请求体
{
    "date":"2020-03-07 12:12:12"
}
  • web 服务器 的控制器
@PostMapping("put")
public User put(@RequestBody User user){
    System.out.println(user.getDate()); // Sat Mar 07 20:12:12 CST 2020
}

2.1.2 为什么传入时间是12点,转成对象就成20点。

源码注解说了,默认是UTC时间,也就是说,服务器认为你传入的12点是0时区的12点,而我web服务器现在在东8区,而东8区,比0时区快8小时,所以转成对象就成了20点。

2.2 指定timezone

2.2.1 修改实体

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date date;

2.2.2 再次测试:

结果:

Sat Mar 07 12:12:12 CST 2020

解释:

  • 你传进来值,我认为是东8区的CST时间,我web服务器的时区也是东8区。所以结果不需要改变。

2.3 正确用法2,输出

  • web服务器实体bean
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") // 未指定 timezoneprivate Date date;
  • web 服务器controller
    @GetMapping("getDate")public User getDate(){
    User user = new User();Date date = new Date();System.out.println(date); // Sat Mar 07 20:45:41 CST 2020user.setDate(date);return user;}
  • 客户端URL请求获取的结果
{
    "date": "2020-03-07 12:45:41"
}

2.3.1 解释:

未指定timezone,也就是说,要输出的日期字符串的时区是0时区,而现在的web服务器的时区是东8区,new Date()时,就是当前时区的标准时间,0时区比当前web服务器的东8区,慢8小时,所以转成UTC 的0时区后 的时间就是20-8=12 ,也就是 客户端URL请求获取的结果。

timezone = “GMT+8” 就不测了。类似

3. 总结

  1. timezone 就是假定客户端传入和给客户端传出的时间在哪个时区。

PS

如果帮助到你的话,点个赞鼓励下,欢迎加入我的置顶博客的javaweb交流群,不搞带课推广,让我们一起向诗靠拢。

  相关解决方案