postgres - 日期时间自动转换
Posted
技术标签:
【中文标题】postgres - 日期时间自动转换【英文标题】:postgres - date time is automatically converted 【发布时间】:2022-01-09 16:46:16 【问题描述】:在调试模式下使用 vscode,当我将鼠标悬停在日期字段上时,它显示为下图。
但是当我注销它时,它会转换为
"execution_date":"2021-12-02T20:23:48.322Z"
这是负 7 小时。
该字段作为时间戳存储在 AWS RDS 上的 postgres 数据库中,运行 show timezone;
返回 UTC,我在 GMT+7 时间使用 VSCode。由于日期已更改并用于调用api,因此如何解决此问题,因此返回的结果将不正确。
【问题讨论】:
字段是timestamp
还是timestamp with time zone
?使用psql
会为该服务器返回什么show timezone;
?添加答案以更新您的问题。
@AdrianKlaver 该字段是时间戳,运行 show timezone;
返回 UTC。调试时将鼠标悬停在 execution_date 字段上时,它显示的日期和时间与存储在数据库中的日期和时间相同,但是当它被注销并用于调用 API 时,它会减少 7 小时。
您现在已经了解了如果您关心时区,为什么不应该使用timestamp
。阅读Date/Datetimes 8.5.1.3。时间戳。短版您的datetime
被假定为UTC
进入。回到你的时间:select '2021-12-02T20:23:48.322Z' at time zone 'ICT'; 2021-12-03 03:23:48.322
@AdrianKlaver 但是在调试时为什么它显示的时间与存储在数据库中的时间相同,但是当注销并用于调用 API 时,它得到了负 7 小时。我认为这与我的操作系统或 VSCode 有关吗?
@AdrianKlaver 抱歉,不知道为什么,但我无法编辑上述回复。在数据库中它存储为2021-12-03 03:23:48.322
,文档指出the resulting value is derived from the date/time fields in the input value, and is not adjusted for time zone.
,我正在使用Sequelize,并且生成的查询没有设置任何时区,所以它不应该是负7小时,这是正确的。
【参考方案1】:
这不是一个完整的答案,因为这取决于更多信息。相反,它是对正在发生的事情的解释,可以帮助您排除故障:
set TimeZone = UTC;
show timezone;
TimeZone
----------
UTC
--Show that timestamp is taken at UTC
select now();
now
-------------------------------
2021-12-05 18:23:38.604681+00
--Table with timestamp and timestamptz to show different behavior.
create table dt_test(id integer, ts_fld timestamp, tsz_fld timestamptz);
--Insert local time 'ICT'
insert into dt_test values (1, '2021-12-03 03:23:48.322+07', '2021-12-03 03:23:48.322+07');
--The timestamp entry ignores the time zone offset, while the timestamptz uses it to rotate to UTC as '2021-12-03 03:23:48.322+07' is same as '2021-12-02 20:23:48.322+00'
select * from dt_test ;
id | ts_fld | tsz_fld
----+-------------------------+----------------------------
1 | 2021-12-03 03:23:48.322 | 2021-12-02 20:23:48.322+00
--timestamp takes the value as at 'ICT' and then rotates it to the current 'TimeZone' UTC. The timestamptz takes the value at UTC at rotates it to 'ICT'
select ts_fld AT TIME ZONE 'ICT', tsz_fld AT TIME ZONE 'ICT' from dt_test ;
timezone | timezone
----------------------------+-------------------------
2021-12-02 20:23:48.322+00 | 2021-12-03 03:23:48.322
我猜测在获取 API 值的过程中的某个时间点,代码采用 timestamp
值并使用一些等效程序在数据库或下游应用 AT TIME ZONE 'ICT'
。
【讨论】:
【参考方案2】:我发现了问题,这与Sequelize和postgres如何处理timestamp without timezone
有关。如果你有和我一样的问题,请参考以下链接:https://github.com/sequelize/sequelize/issues/3000
【讨论】:
这里指出的是,如果您关心时区,您应该使用timestamptz
类型。
@AdrianKlaver 这实际上是一个已经存在的系统。谢谢,从现在开始我会更加注意时间戳。以上是关于postgres - 日期时间自动转换的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Postgres 和 GraphQL 在特定日期自动触发事件?
将提取的文本字符串转换为 Postgres 中字符串长度不同的日期