我很想知道我正在考虑的是不好的做法,或者如果因为这是一个特定而慎重的选择,那实际上是一个不错的主意。 我想存储特定城市中发生的事件的日期信息。我想将这些数据存储为UTC时间戳。 简单地存储时间戳和城市ID /国家ID(与特定时区相关联)而不是存储每个事件的时区不是一个好主意吗? 我问,因为时区可以改变,但城市ID在数据库中永远不会改变。一旦服务器在时区更改的(不太可能的)事件中与最新时区同步,该事件将是独立的并且不受该更改的影响。但是,假设时区改变了它的边界,那么之前在该时区发生的事件可能在它之外。 这样做似乎不明智吗?我只是想知道,我一直在寻求最佳实践,但在这种情况下,这实际上似乎是一个好主意。这特别是因为应用程序设计模型永远不会改变 - 事件将始终与特定城市相关联。
基本流程是:
带有日期/位置的事件数据以ISO-8601 YYYY-MM-DD字符串等标准格式进入系统。
系统将日期转换为UTC时间戳,并使用该时间戳和事件的城市ID将事件存储日期。
当用户请求查看该事件时,系统会提取与该事件相关的时间戳和城市信息,并使用该城市的时区在显示时相应地格式化日期。
这是一个糟糕的主意吗?这有什么好处,存储TZ Offset的概念是否同样可以消除这个问题呢?
答案 0 :(得分:4)
无论你采用哪种方式,它都会以不同的方式失败,具体取决于变化。
如果您将时间戳在相应的时区中存储为2013-12-29 12:34:56 America/New_York
,那么如果布朗克斯突然以不同的偏移量启动自己的时区America/New_York_Bronx
并且您的事件恰好是在布朗克斯区。
决定这种可能性以及失败的程度。
如果您以UTC格式存储时间戳,并且事件发生的时区正在重新定义其偏移量(例如,将DST日期转移或完全转移到不同的偏移量),则事件时间可能与实际墙壁不同那个位置的时钟时间。如果您在德国柏林13:34:56举办活动2013-12-29 12:34:56 UTC
,并且柏林将DST转移,2013-12-29 12:34:56 UTC
现在可能对应柏林当地时间14:34:56,而活动实际上仍然发生在当地时间13:34。
决定这种可能性以及失败的程度。
如果存储UTC时间戳并将其链接到您链接到时区的物理位置,则可以解决这两个问题。但为此你必须存储精确的物理位置,而不仅仅是“纽约”,否则你只需要一个案例1.还有一个中间步骤。如果您确实存储了精确的物理位置并且具有将此位置解析为时区的精确方法,并且您使时区数据库保持最新,则可以处理几乎所有更改方案。
决定这是多么实用,以及这种额外的精确度值多少。
答案 1 :(得分:4)
安排未来时间本质上是 hard ,因为您不知道将来会发生什么变化。与记录过去的时间完全不同。
对于过去的时间事件,您真正需要的只是本地日期和时间,以及与UTC的偏移(许多平台称之为“DateTimeOffset”)。
但是对于未来的事件,你不一定知道偏移量是多少。根据您当前对时区信息的了解,您可以猜测它是什么,但该信息可能会发生变化。实际上,随着世界各国政府改变对夏令时和其他情况的看法,它每年都会发生多次变化。
由于无法可靠地确定偏移量,因此您也无法确定确切的UTC时间戳。因此,保持原始的当地时间非常重要。如果您要计算UTC时间戳,则每次更新时区数据时都应重新计算。
我已多次写过这篇文章,(here,here和here)。我建议你阅读这些帖子。
现在你提出了一个我之前没有提到过的观点,否则我会把你的问题标记为副本。那就是 - 如果事件的位置完全移动到新的时区,因为时区边界已经改变了呢?
我同意Deceze的观点,你需要考虑这种情况的可能性以及失败的程度。在我看来,可能不值得投入大量时间。如果您将来安排了某个活动,并且该位置会进入新的时区,您可以随时返回并编辑该活动。您需要问自己应用程序预计会有多少关于时区变化的详细信息。我使用过的大多数调度系统都没有处理这方面的问题。
如果它确实是你想要处理的东西,那么你需要的不仅仅是城市。您应该存储该位置的纬度和经度坐标。然后,您可以使用these methods之一从这些坐标中解析时区。但另请注意,您需要确保时区边界的来源尽可能最新。
另请注意,作为时区数据原始来源的IANA Time Zone database根本不保留边界数据!大多数边界数据来自独立来源,例如Eric Muller's shapefiles,截至今天与IANA数据库的2013b数据(2013i)一致,因此至少有7次更新时间区域数据要么没有改变任何边界,要么没有跟踪更改。
答案 2 :(得分:1)
当我们将项目从UK托管迁移到美国机器时,当我们必须向客户端显示数据时,存储为DATETIME的一些数据存在问题。我们不得不暂时改变服务器配置,但它将日期保留为db中的字符串或日期时间戳,使它们依赖于服务器配置并不是一个好主意。从那时起,我们确实对系统中的任何日期使用unix时间戳,我们一劳永逸地解决了时区问题。客户决定使用他们想要看到的时区。计算时差,过滤数据等要容易得多。
唯一的问题是确保输入的数据进入系统正确转换为unix时间戳。这意味着,当日期转换为时区时,输入数据的用户应该(在您的情况下)事件的时区,否则用户将需要自己计算时区。