我正在尝试处理输入数据,在保存时添加时间戳
tsSrc timestamp with time zone;
...
tsSrc := strTelegram.rte_data[ iPos ];-- this input data datetime
-- string e.g.'2015/12/13 21:35:26.000'
...
insert into telegram(
tld_id,
ddt_num, tld_src_timestamp,
tld_dst_timestamp, tld_year, tld_month,
tld_day, tld_hour, tld_min,
tld_sec, tld_data
) values(
uuId,
strTelegram.rte_type,
tsSrc,
strTelegram.rte_dst_timestamp,
extract(year from tsSrc), extract(month from tsSrc),
extract(day from tsSrc), extract(hour from tsSrc),
extract(minute from tsSrc), extract(second from tsSrc),
strTelegram.rte_data
);
但是我得到了意想不到的结果,
tsSrc
保存为2015-12-13 20:35:26+03,即有小时-1班次,同时extract(hour from tsSrc)
返回正确的值并保存为21。我是什么做错了吗?
时区在 postgresql.conf 中设置为“MSK-3”,
select now()
返回正确的日期时间,postgresql 9.3。
了解
timestamp
(timestamp without time zone
) 和 timestamptz
(timestamp with time zone
) 的处理以及它们如何与当前会话的 timezone
设置交互。
为了解释您观察到的“差异”,我们需要知道确切的表定义、保存行的会话的
timezone
设置,以及显示行的会话的 timezone
设置。
例如,如果您采用
timestamp
文字 '2015-12-13 21:35:26'
(使用 ISO 格式以避免输入格式产生额外的复杂性!)并将其保存到时区偏移为 timestamptz
及更高版本的会话中的 +2
列选择时区偏移量为 +3
的会话中的同一行,然后您将看到您所看到的:
SELECT '2015-12-13 21:35:26'::timestamp AT TIME ZONE '+2' AT TIME ZONE '+3';
结果:
'2015-12-13 20:35:26'
换句话说:
timestamptz
值'2015-12-13 20:35:26+03'
与'2015-12-13 21:35:26+02'
完全相同(同一时间点),只是显示已适应您的时区设置。当您根据世界角落墙上的时钟来处理 timestamptz
值时(就像处理 extract(hour from tsSrc)
一样),您会得到不同的结果,具体取决于您当前所在的位置(会话的 timezone
设置) .
详细说明: