将时区添加到PostgreSQL中的时间戳(不转换为该时区)

Fly*_*Fly 5 postgresql timezone datetime gtfs

我有3个单独的类型字段VARCHAR(包含时区,例如“欧洲/罗马”)DATEINTERVAL。我想将它们组合在查询中,以便得到TIMESTAMP WITH TIME ZONE。取得此值的规则是:

在给定的时区中指定日期的正午,减去12小时并加上给定的时间间隔(此-12小时需要处理DST)。

显然,加/减INTERVAL不是问题。我的问题是我不了解如何创建“给定时区中指定日期的正午”。

一个简单的例子:

  • 如果我有时区字段“欧洲/罗马”
  • 日期是2018-03-24(该时区的DST切换日期)
  • 间隔为“ 1小时”

计算应如下所示:

  1. 创建指定日期的中午:2018-03-24 12:00:00'欧洲/罗马'时区
  2. 减去INTERVAL '12 hours',结果是'欧洲/罗马'时区的2018-03-24 01:00:00(由于DST)
  3. 添加INTERVAL '1 hour',最终结果是“欧洲/罗马”时区的2018-03-24 02:00:00

如何执行第1点?

PS我不能更改数据架构。它来自加载到postgres中的GTFS数据。简而言之,该模式的独特之处在于它将时区,日期和时间间隔存储在3个不同的表中:agencycalendar_datesstop_times(嗯,时区可能在其他表中,但这对这个问题并不重要)。

Lau*_*lbe 9

您的示例在语法上不正确,但您的问题似乎是 PostgreSQL 将其中包含日期的字符串文字解释为timestamp with time zone.

但你必须走另一条路:你想要中午十二点作为timestamp without timezone,然后使用AT TIME ZONE 'Europe/Rome'获取timestamp with time zone包含“罗马中午”的绝对时间戳(在 PostgreSQL 中称为),然后添加小时。

显示的结果将取决于您的会话时区。

让我们使用 UTC,以便获得相同的结果并在 SQL 中编写以上内容:

SET timezone=UTC;

SELECT '2018-03-24 12:00:00'::timestamp without time zone
   AT TIME ZONE 'Europe/Rome'
   + INTERVAL '1 hour';

        ?column?        
------------------------
 2018-03-24 12:00:00+00
(1 row)
Run Code Online (Sandbox Code Playgroud)

  • 这就需要你知道欧洲/罗马当时是UTC+1。 (3认同)