perl从日期减去一个月

时间:2013-09-10 11:42:51

标签: perl date

我以格式%dd。%mm。%YYYY获取日期,并且我尝试使用Perl减去一个月。

示例:12.07.2013 - > 12.06.2013,30.09.2013 - > 2013年8月31日

我应该使用Date :: Calc吗?有什么想法吗?

由于

2 个答案:

答案 0 :(得分:6)

您可以使用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.201330.09.2013,此代码分别打印11.06.201330.08.2013

strptime函数根据模板将字符串解析为Time::Piece对象。然后我们可以简单地添加/减去对象来操纵日期。这里我使用Time::Seconds模块中的常量,相当于一个月。

这全部来自Time::Piece的文档。

答案 1 :(得分:4)

DateTime支持您正在寻找的按月到月末行为。 end_of_month选项记录在Adding a Duration to a Datetime部分中。我还提供了显示逻辑的Date::Calc解决方案。两种解决方案的输出相同。

<强> DateTime

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');
    }
}

<强> Date::Calc

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