根据前两个答案,最初发布的问题不清楚,因此我完全重写了它:
以下问题仅涉及如何存储数据和存储什么数据,并且在检索时无法转换数据的形式或形式。因此,在SELECT转换到所需的时区不是一个合适的答案。
在带有时区字段的时间戳中插入值时,会在插入时将时间戳转换为数据库的本地时区,从而检索(因此可能存储)。
也就是说,插入2012-01-01 00:00:00+00:00
的时间戳被检索为2011-12-31 19:00:00-05
,其中插入时数据库的本地时区为-05
。使用-04
时区返回在夏令时期间(当数据库位于-04
时)插入的时间戳。
我想要的是所有时间戳在存储时使用任意时区(因此所有时区都可以在没有任何额外工作的情况下进行检索,因为具有该时区)。也就是说,如果服务器围绕行星运行,则所有时间都在+00:00
(任意时区),而不是-12:00
到+12:00
。
我可以插入带时区列的时间戳,以便所有时间戳都相对于任意时区存储吗?如果是这样,怎么样?
原文如下。
将值插入timestamp with time zone
字段时,会将其转换为服务器的当前时区。
示例:如果我插入指定时区-1
的值,则检索它将返回-5
(服务器插入时的时区)的时间。< / p>
是否可以指定应使用任意时区存储?
注意:这个问题不是如何将返回的时间转换为另一个时区,这具体到时间的存储方式。
答案 0 :(得分:1)
将值插入timestamp with time zone
字段时实际发生的是时间戳转换为UTC。另一个问题是该值在输出上转换的时区。有几种方法可以控制它:
当输出带有时区值的时间戳时,它始终是 从UTC转换为当前时区,并显示为 该地区的当地时间。要查看另一个时区的时间,也可以 更改时区或使用AT TIME ZONE构造(请参阅Section 9.9.3)。
答案 1 :(得分:1)
您必须另外将时区偏移保存到timestamp
。
正如@Milen已经解释过(并链接到manual):timestamp
只保存一个时间点(作为抽象值)。时区修改器不已保存,仅用于调整相对于timestamp
的{{1}}。
考虑以下演示:
UTC
在本地运行以查看。请特别注意AT TIME ZONE构造的详细信息,以及如何从(本地!)-- DROP TABLE tbl;
CREATE TEMP TABLE tbl (id int, myts timestamptz, mytz interval);
INSERT INTO tbl VALUES
(1, now() , EXTRACT (timezone from now()) * interval '1s')
,(2, '2012-01-01 00:00-05', interval '-5h')
,(3, '2012-01-01 00:00+04', interval '4h')
,(4, '2012-11-11 20:30+03', interval '3h');
SELECT *
,(myts AT TIME ZONE mytz)::text
|| CASE WHEN mytz > '0:0' THEN '+' ELSE '' END
|| to_char(mytz, 'FMHH24:mi') AS timestamp_at_origin
FROM tbl;
中提取时区。
timestamp with time zone
简称now()
或timestamp with time zone
。
timestamptz
EXTRACT (timezone from now()) * interval '1s'
显示时区的时间戳,如其原点所示。如果我理解你的问题,那就是你在寻找的
您可以进一步改进格式化。
您可能对此related question感兴趣,这可以解释时区的模糊性和陷阱。
答案 2 :(得分:0)
答案 3 :(得分:0)
我总是将时间存储在GMT中,以便客户端可以根据当前的GMT偏移进行转换(GMT offest在大多数语言中都可用)。
我编写C# - 所以当我将数据存储在数据库中时,我可以使用DateTime.ToUniversalTime()
轻松地将所有DateTime对象转换为GMT。
我不确定您使用的是哪种语言或如何在postgressql中将所有时间转换为GMT,但从逻辑角度来看 - 在GMT中存储所有时间将允许所有其他时区可以轻松关联的统一时区。
希望这有帮助!