All datetimes stored in utc
我正在构建一个c#calendar应用程序,并将所有日期时间存储在Microsoft SQL-Server DateTime2类型中。此数据类型可使用">","> ="等运算符进行搜索。
我现在已经阅读了有关该主题的更多内容,例如这些帖子:
夏令时和时区最佳实践
如何存储重复日期,记住夏令时
以UTC格式存储时间总是一个好主意,还是在本地时间存储更好?
我相信在使用UTC和处理不同的DST值时,尤其是在与未来重复事件相关时,我犯了一个错误。
我当前的实现适用于事件,直到重复序列超过DST时间更改。
我相信我现在需要存储
当地时间,
当地时区
可能还有UTC时间
我应该如何构建我的数据库以及我应该使用哪些数据类型将数据存储在数据库中,该数据库将支持不同的客户端时区和DST值,同时还允许我查询指定的开始和停止日期时间范围内的匹配?
-
存储UTC时间肯定是一个好主意,UTC可以转换为任何其他时区,考虑到夏令时,反过来并不总是可行。 UTC是连续的,其他方案通常不是。因此,将UTC存储在数据库中,使用UTC进行计算并仅将其转换为显示是避免许多问题的好方法。
-
我注意到的问题是,在2周内通过fullcalendar查看我的事件时,时钟会发生变化,未来事件不在正确的当地时间,因为它们处于精确的UTC时间,而与DST /时区无关
-
好吧,我知道,那么你真的必须将时区存储到输入的日期时间,你是对的。人们应该真正考虑处理这种夏令时,不管怎样他们都不知道他们正在拯救什么。
-
是的,我想你也知道如何为c#,MSSQL应用程序存储这些内容,这些应用程序还支持在日期时间范围内进行搜索?
-
这将如何与多个全球时区一起使用?
-
@martinstoeckli:时区绝对重要。不同的时区将在不同日期更改夏令时。对于在多个时区参加的重复事件,您必须知道所涉及的时区。
-
来到这个晚了,但同意乔恩100%。通过本地区域安排未来事件需要您保留本地区域和本地时间。否则,如果本地和UTC之间的关系在您的事件发生之前发生变化,您将根据以前的情况进行激发,而不是当时的实际情况。
-
@martinstoeckli:但是为什么你会忽略输入和输出的夏令时?它以其他用户的本地时间更改事件发生的时间。例如,如果我的事件总是在太平洋时间上午10点...那么对于在伦敦时区的用户,事件发生在下午3点,下午4点或下午5点,具体取决于具体日期。你为什么不想要这些信息呢?
-
@JonSkeet - 为了避免更长时间的讨论,我写了一个答案并删除了我以前的一些评论。
-
我现在意识到我将能够以UTC格式存储我的所有数据但我必须在本地时间生成新的事件,然后在保存之前将它们转换为UTC。谢谢您的帮助
对于重复的事??件,你肯定需要存储时区,是的,我会存储本地日期/时间。您可能还希望存储第一个匹配项的UTC值,如果这对比较有用。理论上你可以只存储第一个日期/时间的UTC出现,因为它可以明确地转换为当地时间(如果你有时区) - 但你可能只需要当地时间,执行这些转换的情况可能毫无意义。
您还应该考虑如何处理时区数据的更改 - 因为时区规则确实经常发生变化。 (当然,这取决于国家。)例如,为了提高效率,您可能希望生成一定数量的事件并存储每次事件的UTC日期/时间(已经确定如何处理由于跳过和模糊的当地时间DST转换) - 但如果时区数据发生变化,则需要再次对所有重复事件执行该生成步骤。
-
感谢您的输入,但我也想知道如何在数据库中对此进行建模。必须检索数据集然后解析utc时间和偏移量然后查询结果以进行时间范围过滤器似乎不是很有效。我将如何构建这个
-
@Dizzle:我不知道"搜索时区结果"是什么意思。同样,您可能希望存储UTC值以及本地值,精确地用于搜索而不进行转换,但很难知道除此之外的要求是什么。
-
我只需要在多个时区用户的开始停止日期时间范围内进行搜索。我不明白的是,如果我有一个本地时间的条目和一个带有时区字符串的条目,我如何在运行时搜索它而不将它们变成日期时间对象?
-
@Dizzle:每个用户都想在自己的时区搜索。因此,您需要将每个事件的每个事件转换为本地时区并搜索本地时间,或将搜索转换为UTC(这并不总是有意义)并搜索UTC时间。我个人认为,从搜索的角度来看,保持本地事件最有意义。 (仍然是一个DateTime,只是一个本地的。)
-
在谈论当地时间我们是指用户还是服务器?如果为用户本地时间存储,不同时区的多个用户如何搜索相同的数据集?
-
@Dizzle:用户。服务器时区无关紧要。因此,如果您在不同时区有多个用户,则可能需要多个数据副本,每个区域一个。这实际上取决于您需要支持的搜索类型。
-
我现在意识到我将能够以UTC格式存储我的所有数据但我必须在本地时间生成新的事件,然后在保存之前将它们转换为UTC。谢谢您的帮助
-
@Dizzle:你也需要时区 - 否则你将无法预测下一次出现的时间。
-
是的我现在明白我需要重复配置的时区。
-
@JonSkeet很棒的答案。但是,请您详细说明生成一定数量的事件并存储每次事件的UTC日期/时间的原因和优势?为什么不在当时生成一个未来的事件呢?谢谢。
-
@JonSkeet另外,我很想听听您对存储重复未来事件的技术有何看法:stackoverflow.com / a / 16659802/1677480。
-
@damirstuhec:我不知道你所说的"当时的未来发生"是什么意思,但如果你希望用户经常看"今年和明年",但只是偶尔看一年,那么效率会更高扩展一次重复并缓存常见情况(今年/明年)的事件,而不是每次用户查看日历时扩展事件。
-
@damirstuhec:至于数据库的想法 - 第一个想法在处理带有时区的非日期事件方面不起作用,例如:"每周一下午5点在欧洲/伦敦时间",因为它们不会均匀分布。第二种想法很适合在某一天发现事件,但在扩大特定的复发方面没有帮助。基本上,您需要针对不同用例使用不同的技术。
-
@JonSkeet我的用例是每周一次的活动:"欧洲/伦敦时间每周六晚上10点"。用户只对下一个事件发生时感兴趣,而且在此之后他们看不到那些事件。
-
@damirstuhec:然后针对您的特定用例做正确的事情 - 但不要认为它适合其他所有人。 (我不打算详细介绍存储的内容等等 - 如果你想了解更多信息,你应该问一个新问题。评论主题不适合这样的事情。)