解决处理时区的多个问题

Untangling multiple issues in handling timezones

提问人:Jerome 提问时间:9/23/2023 更新时间:9/23/2023 访问量:24

问:

应用程序配置的时区不是 UTC。它还设置

config.timezone = 'Bogota'
config.active_record.default_timezone = :local` 

其动机是使用应用程序的主要时区设置系统时间戳。

但是,应用程序收集 datetime 类型的数据以及发生该数据的时区。记录的参数包括:

"event"=>{"name_last"=>"tz event", "date(3i)"=>"1", "date(2i)"=>"1", "date(1i)"=>"1987", "date(4i)"=>"01", "date(5i)"=>"01", "tz"=>"Hawaii"

数据库必须具有不同的属性:一个用于日期时间

    t.timestamptz "date"
    t.string "tz"

目标是让用户能够在提供的 UTC 中查看 timestamptz 属性。 tz

问题在于,输入的处理方式就好像它在应用程序的配置时区中一样。删除时区配置并全面使用 UTC 是否更明智?

如何处理这些参数以正确保存带有 postgresql 中输入时区的记录 - 考虑到潜在的夏令时 - 然后使用两种数据表示(UTC 和事件的时区)查看?

Ruby-on-Rails 日期时间 时区

评论


答:

2赞 Heiko Theißen 9/23/2023 #1

如何在数据库上存储时间点应取决于它们所描述的事件本质上是否与时区相关。这对将来的事件会有所不同,因为时区的定义可能会在事件写入数据库之后但在事件到达之前更改。

下面是与时区相关的事件的示例:

假设下一次大选的投票站在我的时区为 2025-09-21T08:00:00+02:00 开放。但是,如果我的国家在此之前取消夏令时,它们将在 2025-09-21T08:00:00+01:00 开放,而无需明确重新安排。换言之:UTC时间会发生变化(从2025-09-21T06:00:00Z更改为2025-09-21T07:00:00Z),但当地时间不会更改。此类事件应与其本地时间 (2025-09-21T08:00:00) 和时区一起存储。

与时区无关的事件的一个例子是小行星最接近地球的时刻。

但是,将与时区相关的事件转换为其他时区很复杂,因此,如果可以证明(例如,因为它们都位于过去),则将事件存储在 UTC 中会更简单

(但请注意,时区数据库有时甚至会更新过去的几年,例如,在有人发现某个地区在 1835 年至 1839 年之间引入了夏令时之后。

评论

0赞 Jerome 9/23/2023
"...如果这是有道理的(例如,因为它们都在过去撒谎)“非常好。对于过去的某个日期,我的理解是 postgresql 具有考虑 DST 的机制,是吗?
0赞 Heiko Theißen 9/23/2023
我不是postgresql专家,但是 postgresql.org/docs/current/...在将UTC转换为命名时区时,似乎将DST考虑在内。