Postgresql的时区(区域,时间戳)是什么?

时间:2014-10-15 14:17:11

标签: postgresql timezone

我正在尝试添加时区到目前为止,这导致了一个奇怪的结果。 这是我的查询

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)

1 个答案:

答案 0 :(得分: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 manual以及check AT TIME ZONE构建。