perl从日期减去一个月
我以%dd.%mm.%YYYY格式获取日期,并尝试使用Perl减去一个月 示例:2013年7月12日->2013年6月12日,2013年9月30日->2013年8月31日 我应该使用Date::Calc吗?有什么想法吗 感谢您可以使用它,它是自Perl v5.9.5以来的核心模块perl从日期减去一个月,perl,date,Perl,Date,我以%dd.%mm.%YYYY格式获取日期,并尝试使用Perl减去一个月 示例:2013年7月12日->2013年6月12日,2013年9月30日->2013年8月31日 我应该使用Date::Calc吗?有什么想法吗 感谢您可以使用它,它是自Perl v5.9.5以来的核心模块 use strict; use warnings; use Time::Piece; use Time::Seconds; my $t = Time::Piece->strptime(shift, "%d.%m
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
strtime
函数根据模板将字符串解析为Time::Piece
对象。然后,我们可以简单地对对象进行加/减操作来操纵日期。在这里,我使用模块中的一个常量,对应于一个月
这些都是从的文档中获取的。支持您正在寻找的“从月底到月底”的行为。本节记录了月末
选项。我还提供了显示逻辑的解决方案。两种解决方案的输出相同
:
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));
}
}
:
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));
}
}
从9月30日开始减去一个月,到8月31日结束,对于一般的“休息一个月”来说是不寻常的(尽管从7月31日开始一个月,到6月30日结束的相反情况被认为是正常的)。你确定这就是我们需要的吗?请提供更多的示例,以及您迄今为止尝试过的任何Perl代码。
12.07.2013
减去1个月
等于11.06.2013
。显然,OP对一个月的定义有很多疑问,但我希望从目前的示例来看,我们讨论的是日历月计算,而不是固定的天数(或秒)。Time::Piece
有add_months
方法,在这里会产生12.06.2013(当与-1
作为参数使用时)。然而,如果操作的结果是“不可能的”日期,OP所期望的仍然是有趣的,例如2013年2月30日。@SlavenRezicadd_months
似乎没有任何作用,它只生成相同的日期。也许这是模块中有点不规则的函数。perl-MTime::Piece-e'warn Time::Piece->new->add_months(-1)
的结果是Sat Aug 10 14:44:56 2013 at-e第1行。
。今天是2013-09-10,所以这里看起来不错;perl 5.10.1和5.18.1的结果相同,可能是这里安装的默认Time::Piece
。@SlavenRezic Aha,我明白了。出于某种奇怪的原因,它只返回被操纵的对象,而不影响原始对象。所以我必须做我的$t2=$t->添加月份(-1)
。嗯,至少这是原创的。试试perl-MTime::Piece-lwe'$t=localtime$t->add_月(-1);打印$t;'代码>