关于时区的思考
当今存在许多种时区的表示,例如我们常见的以下几种:
1、UTC : 协调世界时
2、GMT : 格林威治时间
3、CST: 中国标准时间(China Standard Time),这个解释可能是针对RedHat Linux。
4、北京时间
注:在这里mysql的CST 与linux的cst时区均表示东8区,但是java中的cst代表的是 美国中部时间。这里可能会导致时区的问题
这些时间的转换可能给我们编程带来一些不好的影响。例如mysql安装之后默认的时区是所在操作系统设置的时区,而使用docker默认安装的时区是UTC时区
UTC + 8:00 = CST
所以在mysql 若使用有关事件内嵌函数例如now(),若你mysql所在的操作系统的时区是北京时间(UTC+8),那么,你now()出来的时间就会比当前时间少8。
这也是科学的,就相当于不同地区时间的转换,我是用的是UTC,现在已知UTC + 8的时间,求UTC时间,不就是减8 嘛!
所以最好的方法就是将mysql服务器所在的操作系统的时间时区,与数据库的时区相对应。
now() = UTC + 8 = 操作系统时区(前提是你的系统时区是东八区的)
查看mysql时区
show variables like ‘%time_zone%’;
mysql修改时区的方法
方法一:修改配置文件
linux 版的修改my.cnf
window版的修改 my.ini
#在配置文件中添加如下配置,前提是系统时区是UTC时区。
#如下配置是指当前操作系统时间加8小时。
default-time_zone = ‘+8:00’
对于java,我们熟知的java.utils包下的date类,该类若是无参创建,内部则是会调用
this(System.currentTimeMillis());
如果要让集群的时间保持一致,可以将集群的时区调准至同一时区。当然也可以使用代码来调准到同一时区,以下是将时间统一到东八区时间。
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
TimeZone utc = TimeZone.getTimeZone("UTC");
utc.setRawOffset(28800000); //相对于UTC的时间偏移量,东8区
System.out.println(utc.getRawOffset());
simpleDateFormat.setTimeZone(utc);
String format = simpleDateFormat.format(new Date());
后端设置的时区或后端所在服务器时区与数据库所在服务器时区最好保持一致,如此,可以避免很多因时区导致的麻烦。当然你也可以在连接mysql的时候设置mysql使用的时区。但是注意CST时区java与mysql所表达的含义是不同的。
对于前端,js代码中的
new Date("DateString");
其内会将DateString的时间看成与当前运行的系统的时区相同,则,若是当前系统的时间使用的是东8区时间,那么,由于Date默认使用的是UTC时区,那么,当直接输出如下代码时,会以本地时区为基准转化为UTC时区时间,也就是少了8小时。
console.log(new Date("DateString"))
但是,当你的系统并不是东8区时间,而是其他时区,那么,结果就不是那么美好了。当我们服务器将以东8区时间转递给前端时,前端接收到以JSON格式的数据串,并将时间字符串转化为Date()对象,此时系统的时区并非东8区时间,但是后端传递的时间是东8区时间。而Date会默认以系统的时区来将结果转化为UTC时区时间。结果可想而知就是错的。
//不同的时区下执行相同的两句代码
console.log(new Date("2021-01-01 00:00:00"))
console.log(""+new Date("2021-01-01 00:00:00"))
//后端传递过来的时间是以东8区的时间为基准的 (GMT+08:00)
//结果
2020-12-31T16:00:00.000Z
Fri Jan 01 2021 00:00:00 GMT+0800 (GMT+08:00)
2020-12-31T22:00:00.000Z
Fri Jan 01 2021 00:00:00 GMT+0200 (GMT+02:00) (混乱的时间)
我们需要指定后端转递过来的时区,尽管当前的时区并非是东8区的时间,但是时间也仍然是以UTC时间为基准的
console.log(new Date("2021-01-01 00:00:00"))
console.log(""+new Date("2021-01-01 00:00:00"))
console.log(new Date(Date.parse('2021-01-01 00:00:00' + ' GMT +8')))
console.log(""+new Date(Date.parse('2021-01-01 00:00:00' + ' GMT +8')))
//结果
2020-12-31T22:00:00.000Z //UTC时间
Fri Jan 01 2021 00:00:00 GMT+0200 (GMT+02:00)(混乱的时间)
2020-12-31T16:00:00.000Z //UTC时间
Thu Dec 31 2020 18:00:00 GMT+0200 (GMT+02:00) //在东8区的2021-01-01 00:00:00时,大马士革当时的时间