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)
其他人建议DateTime
,但它很大,非核心,而且可能很慢.
一个更简单的解决方案是使用内置localtime
和POSIX::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月等事实.它将保持当天的第二/分钟/小时,以及该月的同一天.
如果您有机会安装模块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)