在一般情况下,如果你在乎的时区,在一些通用的格式表示的时间内和转换时间仅用于显示目的。
这适用于您的问题,写一个crontab其次GMT表示。在每台工作机上,转换为本地时间并安装crontab。
前面的问题:
#! /usr/bin/perl
use warnings;
use strict;
use feature qw/ switch /;
use Time::Local qw/ timegm /;
对于这个程序支持转换,用今天的日期,并从当前的cronjob替代的时间。返回调整小时星期几和偏移:
sub gmtoday {
my($gmmin,$gmhr,$gmmday,$gmmon,$gmwday) = @_;
my @gmtime = gmtime $^T;
my(undef,undef,$hour,$mday,$mon,$year,$wday) = @gmtime;
my @args = (
0, # sec
$gmmin eq "*" ? "0" : $gmmin,
$gmhr,
$mday,
$mon,
$year,
);
my($lhour,$lwday) = (localtime timegm @args)[2,6];
($lhour, $lwday - $wday);
}
从目前的cronjob以五场时间规范,并从格林尼治标准时间转换为本地时间。请注意,一个完全通用的实现将支持32(即,2 ** 5)的情况。
sub localcron {
my($gmmin,$gmhr,$gmmday,$gmmon,$gmwday) = @_;
given ("$gmmin,$gmhr,$gmmday,$gmmon,$gmwday") {
# trivial case: no adjustment necessary
when (/^\d+,\*,\*,\*,\*$/) {
return ($gmmin,$gmhr,$gmmday,$gmmon,$gmwday);
}
# hour and maybe minute
when (/^(\d+|\*),\d+,\*,\*,\*$/) {
my($lhour) = gmtoday @_;
return ($gmmin,$lhour,$gmmday,$gmmon,$gmwday);
}
# day of week, hour, and maybe minute
when (/^(\d+|\*),\d+,\*,\*,\d+$/) {
my($lhour,$wdoff) = gmtoday @_;
return ($gmmin,$lhour,$gmmday,$gmmon,$gmwday+$wdoff);
}
default {
warn "$0: unhandled case: $gmmin $gmhr $gmmday $gmmon $gmwday";
return;
}
}
}
最后,主循环从输入读取每行并生成相应的输出。请注意,我们不会销毁未处理的时间:它们会作为注释出现在输出中。
while (<>) {
if (/^\s*(?:#.*)?$/) {
print;
next;
}
chomp;
my @gmcron = split " ", $_, 6;
my $cmd = pop @gmcron;
my @localcron = localcron @gmcron;
if (@localcron) {
print join(" " => @localcron), "\t", $cmd, "\n"
}
else {
print "# ", $_, "\n";
}
}
对于这个八九不离十,crontab的
33 * * * * minute only
0 0 * * * minute and hour
0 10 * * 1 minute, hour, and wday (same day)
0 2 * * 1 minute, hour, and wday (cross day)
输出以下时,在美国中央时区运行:
33 * * * * minute only
0 18 * * * minute and hour
0 4 * * 1 minute, hour, and wday (same day)
0 20 * * 0 minute, hour, and wday (cross day)
出色的工作! – PoorLuzer 2009-12-23 11:42:25