在不同时区安排脚本
有些程序/脚本需要在与系统时区不同的时区的特定时间运行。
Perl 中的 crontab,但它遵循与系统配置所在区域不同的时区和 DST 规则。
这是用例:我将创建一个 Excel 工作表,其中 B 列中包含 PT 时间,并在 C 列中运行相应的程序/Perl 脚本。Excel
工作表中的此信息没有任何具体内容 - 可以是纯文本文件/也是“crontab”条目。
Perl 脚本将从 Excel 工作表中读取数据并在正确的时间运行/生成这些脚本。
需要记住的是,无论 Perl 脚本运行的系统位于哪个时区,它都应该正确运行。
无论脚本是否在纽约、伊利诺伊州或加利福尼亚州的 Box 上运行,它都应该按照太平洋标准时间(考虑 DST)在文件条目中提到的时间生成脚本。
正如我之前所说,“自动”(无需我进行任何显式编程)了解 PT 地区的最新 DST 规则非常重要。
你有什么建议?
也许我可以访问一些显示该地区当前时间的网站并从中扫描时间值,并在正确的时间运行脚本?
有这样的 Perl 屏幕抓取工具友好网站吗?
或者也许我可以使用一些智能 Perl 模块,例如 Schedule::Cron
作为记录, http://www.perlmonks.org/index 提供了大量好的建议.pl?node_id=772934,但是,它们以典型的 at/cron 方式按照系统配置的时区工作。
There are some programs/scripts that need to be run at specific times in a timezone different from the system timezone.
A la crontab in Perl, but one that honors a timezone and DST rules in a region different from that in which the system is configured.
Here is the use case : I will create an excel sheet with the time in PT in column B and the corresponding program/Perl script to run in column C.
Nothing specific about this information being in a Excel sheet - could be plain text file/"crontab" entry too.
A Perl script will read in the data from the excel sheet and run/spawn those scripts at the correct time.
The thing to keep at mind is that the Perl script should run correctly regardless of what timezone the system that it is running on is.
Regardless of whether the script is running on a Box in NY or IL or CA, it should spawn the scripts at the time mentioned in the file entries as per the Pacific Standard Time with DST at mind.
It is very important, as I said before, of it being aware, "automagically" ( without me doing any explicit programmming ) of the latest DST rules for the PT region.
What would you suggest?
Maybe I can visit some website that shows current time in that region and scan the time value from it, and run the scripts when it's the correct time?
Any such Perl screen scraper friendly site?
Or maybe I can use some smart Perl module, like Schedule::Cron
For the record, a large number of good suggestions came by at http://www.perlmonks.org/index.pl?node_id=772934, however, they, in typical at/cron fashion, work as per the system configured timezone.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一般来说,如果您关心时区,请以某种通用格式在内部表示时间,并仅出于显示目的转换时间。
将其应用于您的问题,编写一个 crontab,其时间以 GMT 表示。在每台工作计算机上,转换为本地时间并安装 crontab。
前言:
对于该程序支持的转换,请使用今天的日期并替换当前 cronjob 中的时间。返回调整后的小时和星期几偏移量:
从当前 cronjob 中获取五字段时间规范,并将其从 GMT 转换为本地时间。请注意,完全通用的实现将支持 32 个(ie,2 ** 5)个案例。
最后,主循环从输入中读取每一行并生成适当的输出。请注意,我们不会销毁未处理的时间:它们会作为注释出现在输出中。
对于此 sorta-crontab,
在美国中部时区运行时的输出如下:
In general, if you care about timezones, represent times internally in some universal format and convert times for display purposes only.
Applying this to your problem, write a crontab whose times are expressed in GMT. On each worker machine, convert to local time and install the crontab.
Front matter:
For the conversions this program supports, use today's date and substitute the time from the current cronjob. Return the adjusted hour and day-of-week offset:
Take the five-field time specification from the current cronjob and convert it from GMT to local time. Note that a fully general implementation would support 32 (i.e., 2 ** 5) cases.
Finally, the main loop reads each line from the input and generates the appropriate output. Note that we do not destroy unhandled times: they instead appear in the output as comments.
For this sorta-crontab
the output is the following when run in the US Central timezone:
在计划中,存储每次运行应发生的时间点的秒数,而不是日期/时间字符串。
稍微扩展一下:
给我,
因为 2010 年 3 月 14 日凌晨 2:00 是切换发生的时间。另一方面,使用
hour =>; 3
,我得到:1268553600
。现在,在纽约,我使用:因此,解决方案似乎是避免在您的本地时区中不存在的时间安排这些活动。这不需要复杂的逻辑:只需将
DateTime
构造函数调用包装在eval
中并处理异常时间即可。In the schedule, store the number of seconds from the epoch when each run should occur rather than a date/time string.
Expanding a little:
gives me
because 2:00 am on March 14, 2010 is when the switch occurs. On the other hand, using
hour => 3
, I get:1268553600
. Now, in New York, I use:So, the solution seems to be to avoid scheduling these events during non-existent times in your local time zone. This does not require elaborate logic: Just wrap the
DateTime
constructor call in aneval
and deal with the exceptional time.虽然我当然认为可能有“更干净”的解决方案,但以下方法可行吗?
将 cron 设置为比您实际希望脚本运行的可能时间范围提前几个小时运行脚本
处理脚本中的时区检测并让它休眠适当的时间
再次,我知道这是有点笨拙,但我想我会把它放在那里。
While I certainly think that there are likely "cleaner" solutions, would the following work?
set the cron to run the scripts several hours ahead of the possible range of times you actually want the script to run
handle the timezone detection in the script and have it sleep for the appropriate amount of time
Again, I know this is kinda kludgey but I thought I would put it out there.
使用 DateTime 模块来计算时间。
因此,如果您的设置要求每天凌晨 2:30 运行脚本,您将需要逻辑来:
尝试在 America\Los_Angeles 时区的凌晨 2:30 创建一个
DateTime
对象。< /p>如果没有物体,请增加 5 分钟的时间,然后重试。偏移 2 小时后放弃。
一旦有了
DateTime
对象,您就可以与DateTime->now
进行比较,或者从对象中提取纪元时间并将其与DateTime->now
的结果进行比较code>time。请注意,我选择了凌晨 2:30,因为一年中至少不会有 1 天存在这个时间。这就是为什么您需要一个添加偏移量的循环。
Use the DateTime module to calculate times.
So if your setup says to run a script at 2:30 am every day, you will need logic to:
Try to create a
DateTime
object for 2:30am in timezone America\Los_Angeles.If no object add 5 minutes to the time and try again. Give up after 2 hours offset.
Once you have a
DateTime
object, you can do comparisons withDateTime->now
or extract an epoch time from your object and compare that with the results oftime
.Note that I chose 2:30 am, since that time won't exist at least 1 day a year. That's why you need to have a loop that adds an offset.