考虑到月份的不同日期,如何在Perl中找回几个月?

dgB*_*gBP 5 perl time date function localtime

我想知道是否有一个内置的Perl函数可以调整日期,如果你需要一个月的时间.例如,如果日期是第31天,如果它没有31天,它将调整为上个月的结束.

如果没有相隔31天(12月/ 1月,7月/ 8月)和2月的月份,我会轻易将其改为30.我只想将日期存储在距当前日期一定的时间内,例如

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

$current_date = join("-", (1900+$year), ($mon+1), $mday);
$one_month_ago = join("-", (1900+$year), ($mon), $mday);
$one_year_ago = join("-", (1899+$year), ($mon+1), $mday);
Run Code Online (Sandbox Code Playgroud)

我可以处理2月份的实例,因为它仅适用于年份,但如果这是在2012年12月31日采取的话,那么带走一个月意味着2012年11月31日,这当然不存在.我以为在问自己复杂的事情之前我会问是否有功能...谢谢:)

oal*_*ers 10

DateTime不是内置模块,但是一旦你安装它,它就会使这个数学变得微不足道:

#!/usr/bin/perl
use strict;
use warnings;

use feature qw( say );
use DateTime;

my $dt = DateTime->now;
say $dt->ymd;

$dt->truncate( to => month );

say $dt->ymd;

$dt->add( days => -1 );
say $dt->ymd;

foreach ( 1 .. 12 ) { 
    $dt->add( months => -1 );
    say $dt->ymd;
} 
Run Code Online (Sandbox Code Playgroud)

当我今天(2012年8月29日)运行时,我得到以下输出:

[~] $ perl dt.pl 
2012-08-29
2012-08-01
2012-07-31
2012-06-30
2012-05-31
2012-04-30
2012-03-31
2012-02-29
2012-01-31
2011-12-31
2011-11-30
2011-10-31
2011-09-30
2011-08-31
2011-07-31
Run Code Online (Sandbox Code Playgroud)


Leo*_*erd 9

其他人建议DateTime,但它很大,非核心,而且可能很慢.

一个更简单的解决方案是使用内置localtimePOSIX::mktime功能:

use POSIX qw( mktime );

my @t = localtime $epoch;
$t[4] -= 2;  # $t[4] is tm_mon
my $two_months_ago = mktime @t;
Run Code Online (Sandbox Code Playgroud)

mktime()函数专门处理非规范化值; 它将应对Janurary减去2个月是上一年的11月等事实.它将保持当天的第二/分钟/小时,以及该月的同一天.


Pav*_*sov 8

如果您有机会安装模块DateTime.当你处理约会时,它会给你很多额外的好处.

use strict;
use DateTime;

my $epoch = ...;
my $dt    = DateTime->from_epoch( epoch => $epoch );
$dt->subract(months => 1);

printf "%s", $dt->datetime();
Run Code Online (Sandbox Code Playgroud)