likes
comments
collection
share

nestjs整合typeorm遇到的sqlite3时区问题

作者站长头像
站长
· 阅读数 30

写在最前面

  • CURRENT_TIMESTAMP 返回的当前时间的 UTC 时间, UTC时间与东八区时间相差八小时,中国的时间,采用的是东八区的时间。也就是说,假设你在早上9点执行select CURRENT_TIMESTAMP, 在sqlite3中返回的是凌晨1点
  • sqlite3不支持全局性质的时区设置
  • sqlite3也不像mysql,sqlite3不能在连接配置中指定时区
  • sqlite3使用的utc时间,所以,你的应用最好也用utc时间

如何得到当前本地时间?

SELECT datetime(CURRENT_TIMESTAMP,'localtime')

时间存储的问题

无论你认为你插入的是什么时间,sqlite3最终认为这个时间是个UTC时间。

虽然你已经知道如何获取本地时间了,也将这个本地时间存储到datetime类型的字段了,你从数据库的GUI工具中,看到的也是你的本地时间。但是,重点来了,你通过typeorm获取的时间,依然是UTC时间,并且时间值还是你刚刚插入的本地时间值。啥意思呢?

你以为你插入的本地时间8点(东八区的8点),拿到的应该也是本地时间的8点, 实际上是你插入的本地时间8点(东八区的8点),sqlite3认为你这个时间是UTC的8点,返回的也是UTC的8点(nestjs返回的是is0 8061标准的时间戳),前端一转化,就变成了16点(因为UTC时间比东八区时间早8小时)

有什么问题?

你在开发应用时,

  • 凡是datetime类型的数据保存,都要转换为UTC时间后,再保存
  • 凡是datetime类型的数据条件查询,你也得先将条件的时间转换为utc时间
  • 你通过gui工具看到的时间,你要意识到这个是UTC时间,而非本地时间

辅助工具

将数据库存储的UTC时间,转换为对应的本地时间

SELECT 
    id,created_at, DATETIME(created_at,'localtime'),
    updated_at, DATETIME(updated_at,'localtime'),
    name,flag,enable,remark 
FROM t_project

nestjs整合typeorm遇到的sqlite3时区问题

将本地时间的查询条件,转换为utc时间的条件

SELECT 
    * 
FROM 
    t_project 
WHERE 
    created_at >= DATETIME('2024-05-20 07:00','utc')

DATETIME('2024-05-20 07:00','utc') 这里的意思是,将2024-05-20 07:00这个本地时间,转化为utc时间

转载自:https://juejin.cn/post/7370138993064017972
评论
请登录