Mysql 和 Mongodb 查看数据时,看着时间都不对(注:和当前时间对不上),其实这和时区有关。

一、new Date()

在终端控制台运行 nodejs,不要用浏览器控制台。new Date() 直接打印,会显示世界标准时间,和北京时间差 8 个时区,即 8h 。
企业微信20210813022624.png
同理,new Date('2020-11-30 14:15:10') 直接打印,结果是 2020-11-30T06:15:10.000Z ,差着 8h 。想要获取当前时区的时间,只需要 toString() 就可以了。

如果想要格式,可使用date-fns的format,简单易用。

二、mongodb 和 mysql

和 JS 的 Date 一样,mongodb 和 mysql 存储的时间,直接显示也是时间标准时间,和北京时间差 8h,如下图所示,”created”: “2021-08-12 09:59:45.000Z”。同理,如果想要显示为当前时区的时间,也只需要toString()即可。
企业微信20210813023418.png
所以,可以直接把这个时间返回给前端,让前端自己去显示当前时区的时间

  1. const d = newDate('2020-11-30T06:19:14.000Z')
  2. d.toString()
  3. //或者使用 date-fns format代码块

如果在查询数据库时,要进行时间比较,那可以按统一标准把时间都换成世界标准时间,进行比较
企业微信20210813024540.png

举例:若要查询 mongodb 里 created 在2020-11-20: 0:00:00到2020-11-30 23:59:59的数据。

  1. const d1 = new Date('2020-11-20: 0:00:00') // 转换为世界标准时间
  2. const d2 = new Date('2020-11-30 23:59:59') // 转换为世界标准时间
  3. // 对 d1 和 d2 ,使用 mongoose 进行比较即可

三、总结

世界上有那么多时区,那么多显示规则。而计算机存储时间的形式都是统一的,也必须统一,否则多乱。所以,只有toString()才分时区,而 Date 数据不分时区,无论在 js 中还是数据库中。


另外,Docker 虚拟机里,默认没有各个时区,需要自己在 Dockerfile 里配置。

  1. # Dockerfile
  2. FROM node:14
  3. WORKDIR /app
  4. COPY . /app
  5. # 设置时区
  6. RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
  7. CMD npm i && npm run prd-dev && npx pm2 log