【发布时间】:2012-10-25 17:27:11
【问题描述】:
我有一个 Postgres 表,其中包含 时钟闹钟(不是真的,但这是类似的,并且更容易解释)。警报由用户设置,分辨率为 1 小时,用户可以来自许多不同的时区。警报每天都在重复。我想可靠地获取应该在一天中的特定时间响起的警报,但我遇到了夏令时问题。我该如何以最好的方式做到这一点?
示例
Alfred 和 Lotta 都住在斯德哥尔摩(距 UTC +1 小时,但 +2h 当它是 DST 时)。
Sharon 住在新加坡(距 UTC +8 小时,没有 夏令时)在冬天,阿尔弗雷德设置了凌晨 4 点的闹钟。警报应该响起 全年当地时间凌晨 4 点。
在夏季,洛塔会设置闹钟 早上 5 点。同样,它应该全年在早上 5 点开始。
与此同时,Sharon 已经设置了上午 11 点的闹钟。所有这些都可以作为 03:00 UTC 存储在数据库中。
如果我在冬天查询数据库以获取应该在 03:00 UTC,我想要 Alfred 和 Sharon 的闹钟。新加坡现在是+7h 来自瑞典,所以新加坡的上午 11 点是瑞典的凌晨 4 点。洛塔的警报 再过一个小时就不会再响了。
相反,如果我在夏天查询数据库中的警报, 应该在 03:00 UTC 响起,我想要 Lotta 和 Sharon 的闹钟。 新加坡现在距离瑞典 +6h,所以新加坡的上午 11 点是上午 5 点 现在的瑞典。斯文的闹钟在一小时前响了。
如何存储并查询数据库?
如有必要,我可以更改数据库架构。目前,我们根本不针对 DST 进行调整,实际上只有一个“小时”整数字段(看起来很愚蠢,时间字段会更好)。
似乎我需要同时存储 UTC 时间和时区信息,但我不知道如何在 Postgres 中最好地实现这一点。我发现 Postgres 有某种时区概念,但据我所知没有时区字段类型。另外,我想我需要在 SQL 中进行一些计算,以确定如何根据时区数据和创建日期在选择中偏移 UTC 时间。我不太擅长 SQL……
我确实想在 Postgres 中解决这个问题,因为可能会有很多“警报”,并且我想避免将所有警报都提取到 Ruby 中并在那里进行过滤所带来的性能问题。 (是的,这是一个 Rails 应用程序。)
【问题讨论】:
-
Postgres 具有强大的时间类型。您是否尝试过使用它们,如果是,它们在哪里失败了?
-
我用
time with time zone字段类型尝试了一些东西。 1)我还需要存储时区以使用它。 Postgres 可以以某种方式促进这一点,还是我将其存储为字符串? 2)即使我有一个时区,我也没有找到如何提取 DST 信息。我的想法:我从时间字段中提取小时,如果需要根据创建日期补偿 dst,则添加/减去 1h ......但我想出的一切都非常复杂,以至于我的经验告诉我我做错了什么. -
@MartinSvalin 日期和时间是痛苦而复杂的,可悲的是。
标签: sql ruby postgresql timezone dst