使用Perl内置模块Time::Piece与Time::Seconds完美处理日期时间
在Perl 5.10以后,Time::Piece与Time::Seconds这两个核心模块配合,可以完成现在绝大多数的日期时间的计算。Perl 以一种很容易地操作内部格式来存储日期和时间,如果有一个'YYYYMMDD'格式的日期,你需要做的是什么:Convert your date (which is in YYYYMMDD format) into Perl's date/time storage format.
Use Perl to manipulate this date and time.
When you want to output the results, you have to convert it back into the format you want.
my $date = Time::Piece->strptime($str1, '%Y%m%d');
$date现在将输入的日期和时间按在Perl看来是可以理解和操作的格式存储。%Y%m%d是一个描述格式,所以Perl知道在哪里可以找到年份、月和月的日。可以参考strftime查看各种格式参数。在上页的例子:
%Y - represents the year with the century, such as 2016.
%m - Represents the month as a two digit number such as 03 or 12.
%d - Represents the date of the month as a two digit number from 01 to 31 if there are that many days in the month.
接下来:操作日期
可以使用另一个模块称为Time::Seconds会带来极大的方便。Time::Seconds定义一些常量像一天(ONE_DAY)使的操作更容易:
my $date = $date - ONE_DAY;
然后将新的对象转化为想要的格式:
$date->ymd("");
This converts $date into a string in the Year-month-day format.
最终:
use Time::Piece # For manipulating and storing the date
use Time::Seconds # For the nice constants such as ONE_DAY and ONE_WEEK
my $date = Time::Piece->strptime($str1, '%Y%m%d');
my $date = $date - ONE_DAY;
my $str2 = $date->ymd('');
日期时间对比
初始化两个 Time::Piece 对象,可支持这些操作符 (<, <=, ==, >=, > and <=>). 示例如下:
use Time::Piece;
my $today = Time::Piece->new;
my $thaterday = Time::Piece->strptime('01/09/2016', '%m/%d/%Y');
if ($today > $thaterday) {
...
}
日期时间计算
Time::Piece对象是不可变的,所以对他们进行的任何操作将返回一个新对象。它提供了操作月及年的加减函数 months and years (“add_months”, “add_years”) ,示例如下:
my $datetime = Time::Piece->new;
my $nextMonth = $datetime->add_months(1); # plus one month
my $lastQuarter = $datetime->add_months(-3); # minus three months
my $nextDecade = $datetime->add_years(10); # plus 10 years
my $lastYear = $datetime->add_years(-1); # minus 1 year
如果需要更加细度的日期时间计算,你就需要调用Time::Seconds模块来实现,该模块提供如下一些运算符: ONE_MINUTE, ONE_HOUR, ONE_DAY, ONE_WEEK, ONE_MONTH, ONE_YEAR, ONE_FINANCIAL_MONTH, LEAP_YEAR, NON_LEAP_YEAR.
use Time::Piece;
use Time::Seconds;
my $time = Time::Piece->new;
my $tomorrow = $time + ONE_DAY;
my $lastWeek = $time - ONE_WEEK;
my $lastMonth = $time - ONE_MONTH;
直接对对象进行加减,是对秒为单位的操作:
my $now = Time::Piece->new;
my $oneminago = $now - 60;
示例一
use v5.12;
use autodie;
use Time::Piece;
use Time::Seconds;
my $date = "25-jan-2016";
#Create the "date object". The `%d-%b-%Y" is format the date is in
my $my_date = Time::Piece->strptime($date, "%d-%b-%Y");
#得到10天前
$my_date -= ( 10 * ONE_DAY ); #Constant from Time::Seconds
say $my_date;#Prints out Tue Jan 15 00:00:00 2013
#Printing it out in dd-mmm-yyyy format you had
say $my_date->mday . "-" . $my_date->monname . "-" . $my_date->year;
示例二
use Time::Piece;
use Time::Seconds;
my $format = '%Y%m%d';
my $str1 = '20160704';
my $dt1 = Time::Piece->strptime($str1, $format);
my $dt2 = $dt1 - ONE_DAY;
my $str2 = $dt2->strftime($format);
say $str2;
示例三
计算当前和之前半小时的日期时间及一周前的同样时间段
use v5.12;
use utf8;
use Encode;
use Time::Piece;
use Data::Dumper;
use Time::Seconds;
my $dt;
my $cdt=localtime;
my $pdt=$cdt - ONE_WEEK;
say $cdt->datetime;
#say 'month:'.pluspair($cdt->mon).',hour:'.$cdt->hour.',min:'.$cdt->min;
my ($chalfhour,$phalfhour)=($cdt - 30 * ONE_MINUTE,$pdt - 30 * ONE_MINUTE);
say 'Current half hour:'.$chalfhour->datetime;
push @{$dt->{cdt}},$chalfhour->ymd.' '.$chalfhour->hms;
push @{$dt->{cdt}},$cdt->ymd.' '.$cdt->hms;
say $pdt->datetime;
say 'One week half hour:'.$phalfhour->datetime;
push @{$dt->{pdt}},$phalfhour->ymd.' '.$phalfhour->hms;
push @{$dt->{pdt}},$pdt->ymd.' '.$pdt->hms;
say Dumper ($dt);
#retrun double dig(如果是一位的话,在前面补足'0')
sub pluspair{
my $givein=shift;
return (length($givein)>1)?$givein:'0'.$givein;
}
将Unix时间戳转为当前本地系统时间
从HBase中取得记录的时戳,由于是毫秒级的,需要转换一下:
my $rcv=int($row->{'value'}/1000);
my $dt = Time::Piece->strptime($rcv,"%s");
$dt += 8 * ONE_HOUR; #转换为本地时区(cst)
return $dt->datetime;
其它可参考的日期时间计算
使用POSIX模块的'strftime'函数来实现日期格式化计算
This is a simple strptime/strftime roundtrip. Since strftime normalises inputs it is simply to just subtract 1 from the mday field.
use POSIX 'strftime';
use POSIX::strptime 'strptime';
my $fmt = "%Y%m%d";
my @t = strptime "20160704", $fmt;
$t[3] -= 1; # 定义到昨天
my $str2 = strftime $fmt, @t;
参考来源:
Perl日期时间处理模块之Time::Piece