代码之家  ›  专栏  ›  技术社区  ›  Schwern

确定数据是否在DST中的有效算法

  •  4
  • Schwern  · 技术社区  · 16 年前

    我正在寻找一个比O(n)更好的算法来确定将来某个日期是否会应用夏令时(以及夏令时的多少)。给定一年、一个月、一天、一小时、一分钟和一个时区(以及Olsen时区数据库的副本),如何有效地确定该日期是否在DST中?我在找算法,不是要调用库函数。

    谢谢您。

    进一步解释:当您创建一个具有未来日期和时区的对象时,我使用的日期库非常慢。结果它做了一个线性计算来计算日期是否在夏令时。不仅如此,它还在对象创建时执行此操作。显然,它可以等到被问到之后,但它也应该更有效率。

    当然,DST规则会改变,日期库无法预测未来,但另一种选择是对本地化日期设置任意上限。

    4 回复  |  直到 16 年前
        1
  •  1
  •   Carl Smotricz    16 年前

    每个人都已经对总是改变DST的问题发表了评论。但我可以接受这样一个前提:我们只是假装目前已知的规则将永远适用。

    要获取DST信息,首先要计算未来日期的年/月/日(如果它还不在该表单中)。然后查找时区,并根据UTC、DST开/关规则和偏移量提取变化。根据年份的不同,可能有几个不同的规则,你一定要为你的“目标”年份选择一个合适的规则。出于以下原因,了解上一年的规则可能会很方便。

    开/关规则将有一个有趣的规范,如“Oct lastSun”:这意味着开关发生在10月最后一个星期天的晚上。

    您需要做的是收集所有这些简洁格式的“规则”,并为每个规则开发一些代码来确定 该规则所指的最后日期 . 现在是12月,所以考虑到我所在时区的一些规则,比如“Mar lastSun”和“Oct lastSun”,日期是2009年3月29日和2009年10月25日。这些日期中哪一个是最近的?十月。十月是一个“关”,所以我们现在必须没有夏令时。

    最糟糕的情况是,您必须重复上一年的两个规则计算。但是没有其他的搜索,所以严格来说是O(1)。

    我在这里找到一个Local/DST/Tz计算器: http://home-4.tiscali.nl/~t876506/WhatDay.html 由于它是一个JavaScript小程序,您应该能够简单地复制代码。但它不能处理所有规则,因此您需要为其余规则添加一些代码。


    更新:

        2
  •  0
  •   sharptooth    16 年前

    你的首要问题是当地政府制定的日光节约规定。后者几乎可以在任何时候通过任何法律,因此以一种你无法预测的方式改变规则。

        3
  •  0
  •   jilles de wit    16 年前

    Doomsday Algorithm 找出给定年份的星期几,并从中计算转换日期。然后可以确定DST在源和/或目标区域设置中是否有效。converion本身只是一个简单的加和/或减一个小时来补偿DST,然后将时区差异考虑在内的问题。

        4
  •  0
  •   Dénes Tarján    16 年前

    嗯,正如我所见,问题的关键是确定一天的工作日,在遥远的将来。

    为此,我建议这样做:

    • 每过400年,整个系统就会转过来,所以先用400除以年数,取整数部分。在400年里,有99个闰年和301个简单的闰年。如果任意一天是星期一,则400年后的同一天将是301+2x99=499(mod 7)-->星期一+2--->星期三。所以你必须这样说:

    wday = (ref_day + 2 * (int)((target_year - ref_year) / 400)) mod 7

    当你有了那年1月1日的工作日之后,你就可以计算DST的转换日期了,正如Carl Smotricz所写的。