【问题标题】:postgres - date time is automatically convertedpostgres - 日期时间自动转换
【发布时间】: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小时,这是正确的。

标签: postgresql date datetime visual-studio-code time


【解决方案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 这实际上是一个已经存在的系统。谢谢,从现在开始我会更加注意时间戳。
    猜你喜欢
    • 2023-03-17
    • 2021-11-10
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    相关资源
    最近更新 更多