近段时间在做项目时,由于是外单,遇到存储到时区与时差问题,对方需求为美国时间。

开始以为存储的一定得为美国时区,即 America/Los_Angeles 时区,但后来慢慢认识到,存储时间并不一定要设为美国时区,当然设为美国时区也没问题,设为 UTC +00:00 标准时区则最为合适。

交互涉及到三方面的时间,即客户端、服务端、sequlize、存储端,它们的最佳设定如下:

各端 设定 转化
客户端 客户端决定 查询时转化为UTC,还原来转化为当前时区
服务端 UTC 无需转化,服务端产生的时间最后由sequlize转化
sequlize UTC 设置UTC时区,入与出均与UTC为准
mysql UTC -

mysql时区设置

临时修改

  1. set global time_zone = '+00:00'; ##修改mysql全局时区为UTC
  2. set time_zone = '+00:00'; ##修改当前会话时区
  3. flush privileges; #立即生效
  4. show variables like "%time_zone%";

永久修改
找到 my.ini/my.cnf 文件,添加默认时区

  1. default_time_zone='+00:00'

修改完重新启动

sequlize时区设置

nodejs与sequlize交互配置

  1. config.sequelize = {
  2. dialect: 'mysql',
  3. ...
  4. pool: {
  5. max: 100,
  6. min: 0,
  7. acquire: 100 * 1000,
  8. },
  9. define: {
  10. underscored: false, //驼峰形式的字段入库
  11. freezeTableName: true // 禁止表加复数
  12. },
  13. timezone: '+00:00' // 设置默认的时区,即入库与出库交互时均转化为UTC时间
  14. };

client时区转化

安装与引入 moment-timezone

  1. import moment from 'moment-timezone'
  2. //将时间转化为当前时区, time为UTC格式时间
  3. function date2Current (time, fmt = 'YYYY-MM-DD HH:mm') {
  4. return moment(time).tz(moment.tz.guess(true)).format(fmt)
  5. }
  6. //将时间加上为UTC的格式,time:YYYY-MM-DD HH:mm
  7. function timeAddToUTC (time) {
  8. return moment.tz(time, "UTC")
  9. }
  10. // 转化为指定的时区
  11. function time2UTC(time){
  12. moment(time).tz('UTC').format('YYYY-MM-DD HH:mm')
  13. }