nestjs整合typeorm遇到的sqlite3时区问题
写在最前面
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
将本地时间的查询条件,转换为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