我应该如何在Perl中确定时区的下一个夏令时(DST)转换时间?

5
我正在开发一个世界时钟Web应用程序,希望添加一个功能来记录每个位置何时以及何时进行夏令时更改。我正在使用DateTimeDateTime::Timezone CPAN模块,它们似乎提供了除此之外的所有可能的函数!DateTime::Timezone是tz/Olson数据库的实现。到目前为止,我正在比较本地偏移和UTC,现在和24小时后都是如此,这使我能够标记影响,但不能确定确切时间。我的概念验证每分钟计算一次。我认为下一步要么是:
  • 使用类似的方法创建一个查找表,用于识别接下来365天中受影响的日期,然后查看这些日期中的每个小时。

  • 以某种方式解析DateTime::Timezone模块中的夏令时规则。

有什么想法吗?我应该指出我对Perl的了解非常基础。


编辑:

看起来另一个选择可能是将其移植到PHP并使用DateTimeZone::getTransitions。这确实返回了一个包含所有转换的数组,但是PHP 5.3.0只添加了可选的timestamp_begintimestamp_end参数以限制范围。


2
如果你正在Linux上运行,你可能想考虑的另一个选项是zdump命令的输出。例如:zdump -v America/New_York - Grant McLean
2个回答

9

DateTime::TimeZone对象的未记录属性_rules会给您提供一个DateTime::TimeZone::OlsonDB::Rule对象的数组。这些对象编码了观察的开始和结束。

my $o = DateTime::TimeZone->new(name => 'Europe/Vienna')->_rules->[1];
say sprintf "%s summertime ends at %s on %s in %s each year", $o->name, $o->at, $o->on, $o->month;

我建议您提交一个bug请求,要求公开并记录此API,以便您的代码可以依赖它,并且DT维护者将对其进行适当支持。请点击这里进行提交。

有趣!我一定会提交这个 bug。 - e100
我已经提交了这个错误报告,但是从回复中我了解到这是内部工作的一部分,不打算公开。我会尽力了解更多信息并在此更新。 - e100
请参考http://www.timeanddate.com/time/dst2010.html。一些国家可能会在仅提前几周宣布更改夏令时观察时间。基于专家系统(例如数据库)的解决方案无法实现最大精度。但是daxim的解决方案对于大多数情况应该是不错的。 - jmz
这是错误报告和回应链接:https://rt.cpan.org/Public/Bug/Display.html?id=59405 - e100

1
您可以使用时区数据库
“公共领域的时区数据库包含代表全球多个地点的本地时间历史的代码和数据。它会定期更新以反映政治机构对时区边界、UTC偏移和夏令时规则所做的更改。”
甚至有一个perl模块可以使用。 “DateTime::TimeZone包含一个名为parse_olson的脚本,将tz源代码编译为Perl模块。它是Perl DateTime项目的一部分,可在GPL和Perl艺术许可证下自由使用。DateTime :: TimeZone还包含一个名为tests_from_zdump的脚本,用于为tz数据库中的每个时钟转换生成测试用例。”
正如您所说,您已经在使用此模块,但似乎没有使用其所有功能。我不确定DateTime :: TimeZone模块通过tz代码公开了多少功能。在这种情况下,您最好调用它。已经有许多网络服务正在使用tz数据库,因此被广泛使用。
您可能应该编写一个perl或shell脚本,定期下载tz数据库源以使规则保持最新。

1
这只是复制粘贴,重申了我问题中的注释。 - e100

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接