我正在寻找比O(n)算法更好的方法来确定未来的日期是否会应用夏令时(以及多少)。给定年,月,日,小时,分钟和时区(以及Olsen时区数据库的副本)如何有效地确定该日期是否在DST中?我正在寻找算法,而不是要调用的库函数。
谢谢。
进一步说明:当您创建具有未来日期和时区的对象时,我正在使用的日期库非常慢。事实证明,它进行了线性计算,以计算日期是否为夏令时。不仅如此,它还在对象创建时执行此操作。显然它可以等到被问到,但它也应该更有效率。
当然,DST规则发生变化,日期库无法预测未来,但另一种方法是对本地化日期设置任意上限。
答案 0 :(得分:1)
每个人都已经对持续改变DST的问题发表了评论。但我可以接受这样的前提:我们只是假装当前已知的规则将永远适用。
要获取您的DST信息,首先要做的是计算您未来日期的年/月/日(如果它不是那种形式)。然后,您查找时区并根据UTC,DST开/关规则和偏移量拉出变化。可能有几个不同的规则取决于哪一年,你想确保为你的“目标”年抓住正确的规则。由于下面解释的原因,也可以方便地了解前一年的规则。
开/关规则将有一个有趣的规格,如“Oct lastSun”:这意味着切换发生在十月的最后一个星期天的夜晚。
您需要做的是收集所有这些简洁格式的“规则”,并为每个规则开发一些代码,以确定该规则指示的最后日期。现在是十二月,所以考虑到我的时区的“Mar lastSun”和“Oct lastSun”等几条规则,这些日期将是2009年3月29日和2009年10月25日。哪些日期更近?十月。 10月与“关闭”相关联,因此我们目前必须没有DST。
无论目标日期是在这些日期之前还是之后,您都可以计算当前(即目标)年份的夏令时开/关日期;如果开/关日期是您目标日期的未来,则只需再次对上一年进行规则计算。请注意,规则可能在间隔期间发生了变化,因此请确保在您正在查看的年份中应用正确的规则。
此计算的最坏情况是,您必须重复上一年的两个规则计算。但是没有其他搜索,所以它严格来说是O(1)。
我在这里找到了一个Local / DST / Tz计算器:http://home-4.tiscali.nl/~t876506/WhatDay.html因为它是一个JavaScript小程序,你应该能够简单地编写代码。但它并不处理所有规则,因此您需要为剩余的规则添加一些代码。
更新:我刚刚注意到你的时间也只有一小时一分钟。这使问题变得复杂一点。如果您的日期不在“切换”日期,那么我上面给出的说明对您没问题。否则,你需要考虑时间。我想最干净的事情就是把时间包括在你决定“最近”的时候。即如果您的目标时间是00:30 UTC并且给定区域的切换时间是01:00,那么目标年份的切换时间仍然是未来,您必须使用上一年的切换时间。出于实际目的,这将意味着“其他”切换时间是最新的,并且其开/关状态适用。
答案 1 :(得分:0)
您的头号问题是由当地政府设定的夏令时规则。后者几乎可以在任何时候通过任何法律,因此以您无法预测的方式改变规则。
答案 2 :(得分:0)
据我所知,每年固定日开始和结束的DST变化(4月的第一个周末,10月的最后一个周末,类似的东西)。因此,您可以使用Doomsday Algorithm查找给定年份的星期几,并从中计算转换日期。然后,您可以确定DST是否在源和/或目标语言环境中有效。收敛本身只是添加和/或减去一小时以补偿DST然后考虑时区差异的问题。
答案 3 :(得分:0)
嗯,正如我所看到的那样,问题在于确定某一天的工作日,远在将来。
为此,我建议这样的事情:
wday = (ref_day + 2 * (int)((target_year - ref_year) / 400)) mod 7
当你在当年1月1日的工作日之后,你可以像Carl Smotricz所写的那样计算DST转换日期。