Postgres:获取最新午夜时区的本地时间戳

时间:2013-05-03 08:18:18

标签: postgresql timezone

我在欧洲/柏林时区(+02),Postgresql以UTC(+00)运行。 我需要在最近的当地午夜日期(我所在时区的当天日期的开始日期)获取带时区的时间戳。

所以如果我们有2013-03-03 14:00:00 + 02

,我的最终结果会是这样的
2013-03-03 22:00:00+00
2013-03-04 00:00:00+02 // the same

我试图用

来获取这个日期
SELECT TIMESTAMP 'today' AT TIME ZONE 'Europe/Berlin'

不幸的是,在00:00和02:00期间产生了错误的日期(前一天午夜),因为UTC时间是前一天的stil,今天似乎使用utc来计算其余时间。

如果我们在欧洲/柏林有2013-03-03 00:05这将返回

2013-05-01 22:00:00+00

如果我想拥有正确的日期,我需要使用

SELECT date_trunc('day', now() AT TIME ZONE 'Europe/Berlin') AT TIME ZONE 'Europe/Berlin';
2013-05-02 22:00:00+00

这是正确的,但非常难看。

此命令是否有更清晰的变体?

3 个答案:

答案 0 :(得分:4)

使用timestamptz。最后的tz表示with time zone

SELECT TIMESTAMPTZ 'today' AT TIME ZONE 'Europe/Berlin'

或者如果你更喜欢它:

SELECT TIMESTAMP with time zone 'today' AT TIME ZONE 'Europe/Berlin'

答案 1 :(得分:1)

将其包裹在一个函数中:

create function midnight() returns timestamptz as $$
  select date_trunc('day', now() AT TIME ZONE 'Europe/Berlin') AT TIME ZONE 'Europe/Berlin';
$$ language sql;

答案 2 :(得分:1)

基于Erwin's answer to a related question,这是我找出方法的最简单,最快的方法:

SELECT timezone('Europe/Berlin', now()::date::timestamp) AS local_midnight_in_utc;

关键是强制转换为时间戳,该时间戳会从日期中删除时区。

您可以使用以下方法测试“ 2013-03-03 00:05”的采样时间:

SELECT timezone('Europe/Berlin', '2013-03-03 00:05'::date::timestamp) AS midnight;

它返回

2013-03-02 23:00:00+00

据解释分析,这大约是datetrunc版本的3倍。基于5次运行的最佳运行时间,运行时间为.017ms vs.0.006ms。