【问题标题】:What timezone(zone, timestamp) of Postgresql does?Postgresql 的时区(区域,时间戳)是做什么的?
【发布时间】:2014-10-15 14:17:10
【问题描述】:

我正在尝试将时区添加到日期,但结果很奇怪。 这是我的查询

SELECT  timezone('GMT+5:30','2014-03-15'::date);

结果值是

"2014-03-14 13:00:00" (timestamp without timezone)

谁能解释为什么它为“2014-03-15”返回“2014-03-14 13:00:00”

我的时区是Asia/Calcutta(GMT+5:30)

【问题讨论】:

  • 您的会话时区是什么? SHOW timezone;
  • 会话时区是"Asia/Calcutta"@vyegorov

标签: postgresql timezone


【解决方案1】:

您可能知道,PostgreSQL 允许函数重载。
要检查名为 timezone 的所有可能函数,请运行以下查询:

SELECT proname,pg_get_function_result(oid),pg_get_function_arguments(oid)
  FROM pg_catalog.pg_proc
 WHERE proname ~ '^timezone$';

如您所见,它们都不接受date 类型作为参数。事实上,这是非常有效的,因为没有时间成分的时区就没有意义。
因此,您的输入转换为timestamp with time zone(基于您提到的结果数据类型),即2014-03-15 00:00:00+XX,其中XX 取决于您的位置。

而且,如果您的位置远远早于 GMT,这会导致时间减法以返回所需区域的时间戳。

此查询报告的内容:

SELECT current_timestamp, setting
  FROM pg_settings
 WHERE name = 'TimeZone';

更新

是的,这棘手的东西。我强烈建议您通读this answer 几遍。

请执行以下操作:

SET TimeZone TO 'Asia/Calcutta'; -- you don't have to do this
SELECT ts AT TIME ZONE 'UTC', ts AT TIME ZONE 'UTC' AT TIME ZONE 'UTC',
       row_number() OVER () rn
  FROM (VALUES (now()),
/* 2 */ ('2014-03-15'::date),
/* 3 */ ('2014-03-15'::date::timestamptz),
/* 4 */ ('2014-03-15'::date::timestamptz AT TIME ZONE 'UTC'),
/* 5 */ ('2014-03-15'::date::timestamptz AT TIME ZONE 'UTC' AT TIME ZONE 'UTC'),
/* 6 */ ('2014-03-15'::timestamp),
/* 7 */ (timezone('GMT+5:30','2014-03-15')),
/* 8 */ (timezone('GMT+5:30','2014-03-15'::date)),
/* 9 */ (timezone('GMT+5:30','2014-03-15'::timestamp)),
/*10 */ (timezone('GMT+5:30','2014-03-15'::timestamp)  AT TIME ZONE 'UTC'),
/*11 */ (timezone('GMT+5:30','2014-03-15'::timestamptz)),
/*12 */ (timezone('GMT+5:30','2014-03-15'::timestamptz)  AT TIME ZONE 'UTC')) t(ts);

并检查输出。

您的案例对应于此处的#4 行。你这里有2014-03-14 18:30:00, 但是由于您在时区+05:30 中,并且函数应该返回timestamp without time zone,因此您将得到2014-03-14 13:00:00

请查找更多关于 these types in the manualcheck AT TIME ZONE 构造的信息。

【讨论】:

  • 因为我的时区是"Asia/Calcutta",即GMT+5:30,我应该得到"2014-10-14 18:30:00" ((2014-03-15 00:00:00) - 5:30)。相反,我得到"2014-10-14 13:00:00"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 2011-05-08
  • 2011-12-14
  • 1970-01-01
  • 2013-03-27
  • 2014-01-24
  • 1970-01-01
相关资源
最近更新 更多