3

我得到格式为 %dd.%mm.%YYYY 的日期,我正在尝试使用 Perl 减去一个月。

示例:12.07.2013 -> 12.06.2013 ,30.09.2013 -> 31.08.2013

我应该使用 Date::Calc 吗?有任何想法吗?

谢谢

4

2 回答 2

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.

于 2013-09-10T12:08:32.730 回答
4

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
于 2013-09-25T20:41:42.647 回答