这是寻找上一个星期一(或任何指定的一周中的某一天)我的答案的简单修改。唯一的困难在于弄清楚你从哪个日期开始。
use DateTime;
sub nth_day_of_month {
my ($nth, $dow, $year, $month) = @_;
my $date = ($nth > 0
? DateTime->new(year => $year, month => $month, day => 1)
->add( days => $nth * 7 - 1)
: DateTime->last_day_of_month(year => $year, month => $month)
->add( weeks => $nth + 1));
$date->subtract(days => ($date->day_of_week - $dow) % 7);
return (($date->month == $month) ? $date : undef);
}
更新:这里有一个稍微更高效的版本。它使用相同的算法,但将add
和subtract
的调用合并在一起,因此只需要进行一次日期计算。
sub nth_day_of_month {
my ($nth, $dow, $year, $month) = @_;
my ($date, $delta);
if ($nth > 0) {
$date = DateTime->new(year => $year, month => $month, day => 1);
$delta = $nth * 7 - 1;
} else {
$date = DateTime->last_day_of_month(year => $year, month => $month);
$delta = 7 * ($nth + 1);
}
$date->add(days => $delta - ($date->day_of_week + $delta - $dow) % 7);
return (($date->month == $month) ? $date : undef);
}