将时区添加到 PostgreSQL 中的时间戳(不转换为该时区)
Add timezone to timestamp in PostgreSQL (not convert to this timezone)
我有 3 个单独的字段,类型为 VARCHAR
(包含时区,例如 'Europe/Rome')、DATE
和 INTERVAL
。我想在查询中将它们组合起来,以便得到 TIMESTAMP WITH TIME ZONE
。这个值的制定规则是:
给定时区指定日期的正午,负12小时加上给定的时间间隔(处理DST需要这个-12小时)
显然adding/subtractingINTERVAL
不是问题。我的问题是我不明白如何创建 "Noon of specified date in given time zone".
一个简单的例子:
- 如果我有时区字段'Europe/Rome'
- 日期为 2018-03-24(该时区夏令时转换日期)
- 间隔为“1 小时”
计算应该是这样的:
- 创建指定日期的中午:2018-03-24 12:00:00 在 'Europe/Rome' 时区
- 减去
INTERVAL '12 hours'
,结果是2018-03-2401:00:00在'Europe/Rome'时区(因为夏令时)
- 添加
INTERVAL '1 hour'
,最终结果是2018-03-24 02:00:00 at 'Europe/Rome' time zone.
第 1 点怎么做?
P.S。我无法更改数据模式。它来自 GTFS data that is loaded into postgres. In short, peculiarity of this schema is that it stores timezone, date and time intervals in 3 different tables: agency, calendar_dates and stop_times(嗯,时区可能在其他 table,但这对这个问题并不重要)。
您的示例在语法上不正确,但您的问题似乎是 PostgreSQL 将其中包含日期的字符串文字解释为 timestamp with time zone
。
但你必须走另一条路:你想要中午十二点作为 timestamp without timezone
,然后使用 AT TIME ZONE 'Europe/Rome'
获得绝对时间戳(在 Postgre[=23= 中称为 timestamp with time zone
]) 包含“罗马的中午”,然后添加小时。
显示的结果将取决于您的会话时区。
让我们使用 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)
我有 3 个单独的字段,类型为 VARCHAR
(包含时区,例如 'Europe/Rome')、DATE
和 INTERVAL
。我想在查询中将它们组合起来,以便得到 TIMESTAMP WITH TIME ZONE
。这个值的制定规则是:
给定时区指定日期的正午,负12小时加上给定的时间间隔(处理DST需要这个-12小时)
显然adding/subtractingINTERVAL
不是问题。我的问题是我不明白如何创建 "Noon of specified date in given time zone".
一个简单的例子:
- 如果我有时区字段'Europe/Rome'
- 日期为 2018-03-24(该时区夏令时转换日期)
- 间隔为“1 小时”
计算应该是这样的:
- 创建指定日期的中午:2018-03-24 12:00:00 在 'Europe/Rome' 时区
- 减去
INTERVAL '12 hours'
,结果是2018-03-2401:00:00在'Europe/Rome'时区(因为夏令时) - 添加
INTERVAL '1 hour'
,最终结果是2018-03-24 02:00:00 at 'Europe/Rome' time zone.
第 1 点怎么做?
P.S。我无法更改数据模式。它来自 GTFS data that is loaded into postgres. In short, peculiarity of this schema is that it stores timezone, date and time intervals in 3 different tables: agency, calendar_dates and stop_times(嗯,时区可能在其他 table,但这对这个问题并不重要)。
您的示例在语法上不正确,但您的问题似乎是 PostgreSQL 将其中包含日期的字符串文字解释为 timestamp with time zone
。
但你必须走另一条路:你想要中午十二点作为 timestamp without timezone
,然后使用 AT TIME ZONE 'Europe/Rome'
获得绝对时间戳(在 Postgre[=23= 中称为 timestamp with time zone
]) 包含“罗马的中午”,然后添加小时。
显示的结果将取决于您的会话时区。
让我们使用 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)