Elo*_*off 8 mysql sql sql-server oracle timezone
这是一个很难的问题.事实上,SQL标准似乎很难,而且大多数主要数据库都没有实现的线索.
将所有日期时间转换为UTC可以轻松比较记录,但会丢弃时区信息,这意味着您无法使用它们进行计算(例如,将8个月添加到存储的日期时间),也不会在存储它们的时区中检索它们.所以天真的方法已经出来了.
除了时间戳(例如,postgres中带有时区的时间戳)之外,存储UTC的时区偏移量似乎已足够,但是不同的时区在一年中的某个点可以具有相同的偏移量,而在6个月之后由于DST而具有不同的时间戳.例如,您现在可以在UTC-4(8月)使用纽约和智利,但是11月4日之后纽约将是UTC-5,智利(9月2日之后)将是UTC-3.因此,仅存储偏移量也不允许您进行准确的计算.像上面的天真方法一样,它也会丢弃信息.
如果您使用时间戳存储时区标识符(例如America/Santiago),该怎么办?这将允许您区分智利日期时间和纽约日期时间.但这仍然不够.如果您要存储过期日期,比如说未来6个月的午夜,并且DST规则发生变化(不幸的是政治家喜欢这样做)那么您的时间戳将是错误的,并且过期可能发生在晚上11点或凌晨1点.对您的应用程序而言可能会或可能不是什么大不了的事.因此,使用时间戳也会丢弃信息.
为了真正准确,您需要将本地日期时间(例如,使用非时区感知时间戳类型)与时区标识符一起存储.为了支持更快的比较,您可以缓存它的utc版本,直到您使用的时区db更新,然后更新缓存的值(如果已更改).因此,这将是2个天真的时间戳类型加上时区标识符和某种外部cron作业,它检查时区数据库是否已更改并为缓存的时间戳运行适当的更新查询.
这是一个准确的解决方案?还是我还缺少什么?可以做得更好吗?
我对MySQL,SQL Server,Oracle,PostgreSQL和其他处理TIMESTAMP WITH TIME ZONE的DBMS的解决方案感兴趣.
你已经很好地总结了问题。可悲的是,答案是按照您所描述的进行。
使用的正确格式确实取决于时间戳应该表示的语用学。一般来说,它可以分为过去事件和未来事件(尽管也有例外):
过去的事件可以而且通常应该被存储为永远不能以不同方式重新解释的东西。(例如:带有数字时区的 UTC 时间戳)。如果应保留指定的时区(以便为用户提供信息),则应将其分开。
未来的事件需要您所描述的解决方案。本地时间戳和命名时区。这是因为您希望在时区规则更改时更改该事件的“实际”(UTC) 时间。
我想问时区转换是否有这么大的开销?通常很快。只有当您看到性能受到真正显着的影响时,我才会经历缓存的痛苦。(正如您所指出的)一些大型操作需要缓存(例如根据实际(UTC)时间对数十亿行进行排序。
如果出于性能原因您需要将未来的事件缓存在 UTC 中,那么是的,您需要制定一个流程来更新缓存的值。根据数据库的类型,这可能由系统管理员完成,因为 TZ 规则很少更改。
| 归档时间: | 
 | 
| 查看次数: | 377 次 | 
| 最近记录: |