我得到格式为 %dd.%mm.%YYYY 的日期,我正在尝试使用 Perl 减去一个月。
示例:12.07.2013 -> 12.06.2013 ,30.09.2013 -> 31.08.2013
我应该使用 Date::Calc 吗?有任何想法吗?
谢谢
您可以使用Time::Piece
,这是自 Perl v5.9.5 以来的核心模块。
use strict;
use warnings;
use Time::Piece;
use Time::Seconds;
my $t = Time::Piece->strptime(shift, "%d.%m.%Y");
$t -= ONE_MONTH;
print $t->strftime("%d.%m.%Y");
给定参数12.07.2013
,30.09.2013
这段代码分别打印11.06.2013
和30.08.2013
。
该strptime
函数根据模板将字符串解析成一个Time::Piece
对象。然后我们可以简单地对对象进行加/减来操作日期。在这里,我使用了Time::Seconds
模块中的一个常量,对应于一个月。
这一切都取自Time::Piece
.
DateTime支持您正在寻找的快速到月底的行为。该end_of_month
选项记录在向 Datetime 添加持续时间部分中。我还为显示逻辑的Date::Calc提供了解决方案。两种解决方案的输出相同。
日期时间:
use DateTime;
my @dates = qw(
01.01.2013
28.02.2013
12.07.2013
30.09.2013
);
foreach my $string (@dates) {
my %p; @p{qw(day month year)} = split /\./, $string;
my $dt = DateTime->new(%p);
for my $n (-1, 1) {
my $res = $dt->clone->add(months => $n, end_of_month => 'preserve');
printf "%s %+d month => %s\n", $string, $n, $res->strftime('%d.%m.%Y');
}
}
use Date::Calc qw[Days_in_Month Decode_Date_EU];
my @dates = qw(
01.01.2013
28.02.2013
12.07.2013
30.09.2013
);
sub Add_Months {
@_ == 4 || die q/Usage: Add_Months($year, $month, $day, $delta)/;
my ($y, $m, $d, $delta) = @_;
my $ultimo = ($d == Days_in_Month($y, $m));
use integer;
$m += $delta;
$y += $m / 12;
$m %= 12;
if ($m < 1) {
$y--, $m += 12;
}
my $dim = Days_in_Month($y, $m);
if ($d > $dim || $ultimo) {
$d = $dim;
}
return ($y, $m, $d);
}
foreach my $string (@dates) {
for my $n (-1, 1) {
printf "%s %+d month => %.2d.%.2d.%.4d\n",
$string, $n, reverse(Add_Months(Decode_Date_EU($string), $n));
}
}
输出:
01.01.2013 -1 month => 01.12.2012
01.01.2013 +1 month => 01.02.2013
28.02.2013 -1 month => 31.01.2013
28.02.2013 +1 month => 31.03.2013
12.07.2013 -1 month => 12.06.2013
12.07.2013 +1 month => 12.08.2013
30.09.2013 -1 month => 31.08.2013
30.09.2013 +1 month => 31.10.2013