我的“事件”表中有“事件日期时间”列,类型为“带时区的时间戳”。我的 python Flask 应用程序正在保存类似
'2014-08-30 02:17:02+00:00'
的日期,但 postgres 会自动将其转换为 '2014-08-30 07:17:02+05'
。它将时间戳转换为我的本地时区,即巴基斯坦。我想保存它而不转换。
我试过了
设置时区='UTC'
它确实将时区更改为“UTC”,但 pgadmin3 仍在保存转换后的时间。
我使用的是 MAC 操作系统和 Postgresql 9.3。
pgadmin 显示小时 +5 的原因是因为您的系统时区设置为这个。 当您在 GMT + 或 - 任何值保存“带有时区的时间戳”值时,系统会将您输入的任何时区偏移到 GMT(或 UTC),以便当您检索它时,您可以指定所需的时区它显示在。
例如,让我们确定纽约的当前时间。
select now()::timestamp with time zone at time zone 'America/New_York';
在询问时,它返回“2014-08-23 08:50:57.136817”。周六早上 8:50,如果你比较迂腐的话,那就是 8:51。
现在,如果我们采用相同的时间并以 GMT 显示它,我们将看到不同的结果:
select '2014-08-23 08:50:57.136817 America/New_York'::timestamp with time zone at time zone 'GMT';
现在有一个新时间“2014-08-23 12:50:57.136817”...进入“未来”5小时!
最后让我们获取原始时间戳并将其显示在我认为是巴基斯坦时区(PKT)的位置,看看它显示什么
select '2014-08-23 08:50:57.136817 America/New_York'::timestamp with time zone at time zone 'PKT';
结果呢? '2014-08-23 17:50:57.136817' 更进一步的未来!
我必须再次强调它能做到这一点的原因是因为它总是将输入时间偏移转换为 UTC 或 GMT。 Postgres 以这种方式处理其所有“带有时区的时间戳”数据类型。它旨在避免夏令时等时区问题。
您的问题似乎是 python 在+00 的偏移量处插入时间,如果这应该是当地时间,那么就 postgres 而言,您将需要 5 个小时的时间。在不确切知道 python 正在执行什么查询的情况下,我假设您可能想要查看它以确保它为您提供了正确的时间,大概
set timezone='PKT'
应该是一个解决方案。无论哪种方式,当您使用 pgadmin 等浏览器查看带有时区的时间戳时,时间戳都会转换为您的本地时区,这就是您看到 +5 的原因。
或者,如果您确实希望查看 +00 处的那些时间,则必须在 SELECT 查询中指定您想要的时间。
在postgresql中,timestamp和timestamptz始终存储在UTC中,两种类型具有相同的64位大小。
可以在当前会话/连接中设置时区,如下所示:
set timezone TO 'UTC';
set timezone TO 'America/New_York';
set timezone TO 'EST5EDT';
set timezone TO 'CEST-1CET';
Postgresql 使用
定义时区我在 postgres 中使用时间戳的规则:
POSIX 格式说明:
时间戳加时间偏移EST5EDT
timezone('EST5EDT', timestamp) -- return type timestamptz
timestamptz 减去时间偏移 EST5EDT
timezone('EST5EDT', timestamptz) -- return type timestamp
时间戳转换为另一个时区
select
'By name - America/New_York' as timezone_format,
timezone('America/New_York', timestamp'2024-03-10 00:00:00') winter_dst,
timezone('America/New_York', timestamp'2024-03-11 00:00:00') summer_dst
union all
select
'by POSIX - EST5EDT' as timezone_format,
timezone('EST5EDT', timestamp'2024-03-10 00:00:00') winter_dst,
timezone('EST5EDT', timestamp'2024-03-11 00:00:00') summer_dst
union all
select
'by POSIX full - AAA5AAA,M3...' as timezone_format,
timezone('AAA5AAA,M3.2.0/2:00:00,M11.1.0/2:00:00', timestamp'2024-03-10 00:00:00') winter_dst,
timezone('AAA5AAA,M3.2.0/2:00:00,M11.1.0/2:00:00', timestamp'2024-03-11 00:00:00') summer_dst;
结果:
set timezone to 'UTC'
+-----------------------------+--------------------------+--------------------------+
|timezone_format |winter_dst |summer_dst |
+-----------------------------+--------------------------+--------------------------+
|By name - America/New_York |2024-03-10 05:00:00 +00:00|2024-03-11 04:00:00 +00:00|
|by POSIX - EST5EDT |2024-03-10 05:00:00 +00:00|2024-03-11 04:00:00 +00:00|
|by POSIX full - AAA5AAA,M3...|2024-03-10 05:00:00 +00:00|2024-03-11 04:00:00 +00:00|
+-----------------------------+--------------------------+--------------------------+
set timezone to 'EST5EDT';
+-----------------------------+--------------------------+--------------------------+
|timezone_format |winter_dst |summer_dst |
+-----------------------------+--------------------------+--------------------------+
|By name - America/New_York |2024-03-10 00:00:00 -05:00|2024-03-11 00:00:00 -04:00|
|by POSIX - EST5EDT |2024-03-10 00:00:00 -05:00|2024-03-11 00:00:00 -04:00|
|by POSIX full - AAA5AAA,M3...|2024-03-10 00:00:00 -05:00|2024-03-11 00:00:00 -04:00|
+-----------------------------+--------------------------+--------------------------+
将时间戳转换为时间戳
select
'by POSIX - use UTC' as timezone_format,
timezone('EST5EDT', timestamptz'2024-03-10 00:00:00Z') winter_dst,
timezone('EST5EDT', timestamptz'2024-03-11 00:00:00Z') summer_dst
union all
select
'by POSIX - use session timezone' as timezone_format,
timezone('EST5EDT', timestamptz'2024-03-10 00:00:00') winter_dst,
timezone('EST5EDT', timestamptz'2024-03-11 00:00:00') summer_dst;
set timezone TO 'UTC';
+-------------------------------+-------------------+-------------------+
|timezone_format |winter_dst |summer_dst |
+-------------------------------+-------------------+-------------------+
|by POSIX - use UTC |2024-03-09 19:00:00|2024-03-10 20:00:00|
|by POSIX - use session timezone|2024-03-09 19:00:00|2024-03-10 20:00:00|
+-------------------------------+-------------------+-------------------+
set timezone TO 'EST5EDT';
+-------------------------------+-------------------+-------------------+
|timezone_format |winter_dst |summer_dst |
+-------------------------------+-------------------+-------------------+
|by POSIX - use UTC |2024-03-09 19:00:00|2024-03-10 20:00:00|
|by POSIX - use session timezone|2024-03-10 00:00:00|2024-03-11 00:00:00|
+-------------------------------+-------------------+-------------------+