【问题标题】:Postgres: get local timestamp with time zone of latest midnightPostgres:获取具有最新午夜时区的本地时间戳
【发布时间】:2013-04-27 14:09:47
【问题描述】:

我在欧洲/柏林时区 (+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 时间仍然是前一天,而今天似乎使用 utc 来计算其余时间。

如果我们有 2013-03-03 00:05 at Europe/Berlin 这将返回

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

这是正确的,但很丑。

这个命令有更简洁的变体吗?

【问题讨论】:

    标签: postgresql timezone


    【解决方案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】:

      使用timestamptz。末尾的tz 意思是with time zone:

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

      或者如果你喜欢更明确:

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

      【讨论】:

        【解决方案3】:

        基于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 倍。 0.017ms 与 0.006ms 的运行时间基于 5 次运行中的最佳值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-19
          • 1970-01-01
          • 2012-01-22
          • 2010-09-27
          相关资源
          最近更新 更多