5

我需要在我的应用程序中使用多个时区。

基本上,我的系统生成数据,地球上任何地方的客户都可以访问它。

由于我的数据具有关联的时间戳,因此我考虑了以下处理时区的策略。

在 Postgres 中:

  • ::timestamptz使用我的时间戳类型创建我的表。没有时区的时间戳将不允许混合::timestamp::timestamptz在我的情况下看起来像一个定时炸弹。

  • 将我的 PG 服务器系统的时区设置为 UTC。

  • 设置(如果系统的 TZ 是 UTC timezone='UTC'postgresql.conf则可能不需要,但我有点偏执,它没有花费我任何费用)。

  • 创建我的表时添加以下检查:

    约束 timestamp_must_be_utc CHECK (date_part('timezone'::text, "my_timestamp_field") = 0::double precision)

  • 以 UTC 存储我所有的时间戳

在客户端(python + pytz

  • 将客户的时区存储在他的个人资料中,例如'America/Los Angeles'

  • 在查询数据时将时区信息发送到 postgres,这样我就可以获得类似的东西SELECT xxxx FROM yyyy WHERE my_ts >= '2012-11-27 19:13:00+01'::timestamptz并让 Postgres 转换为 UTC。或者,我可以使用pytz进行转换,但似乎 Postgres 可以很好地完成这项工作。

  • 根据客户的时区转换时间戳,以便我可以正确显示数据 + 时间戳。

总而言之,我计划在任何地方都使用 UTC 来存储和查询数据,并在显示数据时只进行时区转换。

我对 Postgres 及其处理时区的方式没有太多经验。我知道在不同时区处理日期和时间是多么困难(一旦你必须处理航班时刻表,你就会很难学会使用 UTC 是进行日期和时间计算的唯一可靠方法)这就是我问的原因这个问题让比我更有经验的postgres用户可以确认或纠正我的策略。

有趣的链接:

4

1 回答 1

7

根据喜好为自己泡杯茶/咖啡,留出一个小时左右的时间,阅读手册中有关时间戳处理的详细信息。玩一下,一切都会变得清晰。

如果您使用“带时区的时间戳”(timestamptz),则处理不同的时区没有问题。它确实应该被命名为“绝对时间戳”,并且在内部UTC。不存储时区部分,它仅用于获取绝对时间。

所以 - 确保您的所有时间戳都包含更新时的相关时区,然后适当地设置您的客户端时区。无论提供的时区如何,它们都将在客户的时区返回给您。

它确实变得繁琐的地方在于处理一天并不总是 24 小时(有时一小时不是 3600 秒)以及 DST 发生在不同日期的事实,具体取决于国家和历史。不过那不是 PostgreSQL,那只是现实世界。

于 2012-11-27T20:28:45.600 回答