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

  • Post author:
  • Post category:其他


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



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") // 未指定 timezone
    private 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 2020
        user.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交流群,不搞带课推广,让我们一起向诗靠拢。