我正在开发一个 Rails 应用程序,它将所有日期存储到 PostgreSQL 为“TIMESTAMP WITHOUT TIME ZONE”。(Rails 处理应用程序层的时区,对于这个应用程序来说是“欧洲/柏林”。)不幸的是,夏令时 (DST) 成为一个问题。
简化的“项目”表包含以下列:
started_at TIMESTAMP WITHOUT TIME ZONE
duration INTEGER
项目开始started_at
并运行数duration
天。
现在,假设只有一个项目于 2015 年 1 月 1 日 10:00 开始。由于这是“Europe/Berlin”并且是 1 月(没有 DST),因此数据库中的记录如下所示:
SET TimeZone = 'UTC';
SELECT started_at from projects;
# => 2015-01-01 09:00:00
它应于 2015 年 6 月 30 日 10:00(欧洲/柏林)结束。但现在是夏天,所以 DST 适用,“欧洲/柏林”的 10:00 现在是 UTC 的 08:00。
因此,使用以下查询查找所有持续时间已过的项目对于跨 DST 边界开始/结束的项目不起作用:
SELECT * FROM projects WHERE started_at + INTERVAL '1 day' * duration < NOW()
我想如果上面的 WHERE 在时区“欧洲/柏林”而不是“UTC”中进行计算,那将是最好的。我已经尝试了一些东西,::TIMESTAMTZ
但AT TIME ZONE
都没有奏效。
附带说明:根据 PostgreSQL 文档,+ INTERVAL
在 DST 方面,应该处理与“24 小时”间隔不同的“1 天”间隔。添加天数会忽略 DST,因此 10:00 始终保持为 10:00。另一方面,当添加小时数时,如果您以一种或另一种方式跨越 DST 边界,则 10:00 可能会变为 09:00 或 11:00。
非常感谢任何提示!