使用Time::Piece解决几乎所有日期时间需求

在编程中,日期时间问题经常出现,因此熟练地处理它们是必不可少的技能。CPAN上有许多处理日期时间的模块,但大多数任务只需要一个:Time::Piece

需求

Time::Piece自Perl 5.8版本以来一直是Perl的核心库的一部分,因此您应该已经安装了它。如果没有安装,您可以在终端通过cpan进行安装。

$ cpan Time::Piece

创建一个Time::Piece对象

要创建一个带有当前系统时间的新的Time::Piece对象,请使用Time::Piece导出的版本localtime。

use Time::Piece;

my $time = localtime;

以任何格式获取日期时间字符串

Time::Piece提供了许多用于以常见格式打印日期时间的函数。例如

$time;           # Thu Jan  9 21:21:36 2014
$time->datetime; # 2014-01-09T21:21:36
$time->date;     # 2014-01-09
$time->mdy;      # 01-09-2014
$time->fullday;  # Thursday
$time->hms;      # 21:21:36
$time->epoch;    # 1389320496 (Unix time)

如果您需要获取特定格式的日期时间,Time::Piece提供了一个“strftime”方法,它接受一个自定义字符串格式。完整的格式化代码列表可以在手册页上找到。以下是一些示例

use Time::Piece;

my $time = localtime;
$time->strftime('%y/%m/%d %H:%M'); # 14/01/09 21:21
$time->strftime('%y_%m_%d');       # 14_01_09
$time->strftime('%s');             # 1389320496 (Unix time)
$time->strftime('%Y %y %G %g');    # 2014 14 2014 14 (4 different years,really)

以任何格式读取日期时间字符串

Time::Piece还提供了一个strptime方法,它接受一个字符串和一个字符串格式,并使用该日期时间初始化一个新的Time::Piece对象。如果日期或时间组件缺失,Time::Piece将假定当前日期或时间。以下是一些示例

use Time::Piece;

my $yesterday    = Time::Piece->strptime('01-08-2014', '%m-%d-%Y');
my $yesterdayDMY = Time::Piece->strptime('08-01-14', '%d-%m-%y');
my $lunchhour24  = Time::Piece->strptime('12:30', '%H:%M');
my $bedtime      = Time::Piece->strptime('12:30 AM', '%l:%M %p');

# epoch - no problem
my $from_epoch   = Time::Piece->strptime(1501615857, '%s');

# timezones are easy too
my $utc_datetime = Time::Piece->strptime('Mon, 19 Jan 2015 14:56:20 +0000','%a, %d %b %Y %H:%M:%S %z');
my $eastern_datetime = Time::Piece->strptime('2015-10-05T09:34:19 -0400','%Y-%m-%dT%T %z');
my $pacific_datetime = Time::Piece->strptime('2015-10-05T09:34:19 -0700','%Y-%m-%dT%T %z');

警告 Time::Piece无法解析包含冒号的时区。为了处理这种情况,请在将其传递给strptime之前从时区中删除冒号。

use Time::Piece;

my $datetime = '2015-10-05T09:34:19 -04:00';
$datetime    =~ s/([+\-]\d\d):(\d\d)/$1$2/;
my $dt       = Time::Piece->strptime($datetime, "%Y-%m-%dT%H:%M:%S %z");

strptime使用与strftime相同的格式化代码,您可以在这里找到完整的列表。

比较日期时间

这很简单。只需初始化两个Time::Piece对象,然后使用运算符(<, <=, ==, >=, > 和 <=>)进行比较即可。例如

use Time::Piece;

my $today = localtime;
my $yesterday = Time::Piece->strptime('01/08/2014', '%m/%d/%Y');

if ($today > $yesterday) {
    ...
}

日期时间数学

首先要知道,Time::Piece对象是不可变的,因此对它们执行任何操作都将返回一个新的对象。

Time::Piece提供了一些方法来从Time::Piece对象中添加月份和年份(“add_months”,“add_years”)。只需使用负整数进行减法即可。例如

use Time::Piece;

my $datetime = localtime;
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 = localtime;
my $tomorrow  = $time + ONE_DAY;
my $lastWeek  = $time - ONE_WEEK;
my $lastMonth = $time - ONE_MONTH;

如果您需要以秒为单位更改日期时间,您可以使用整数算术。

use Time::Piece;

my $now = localtime;
my $thirtySecsAgo = $now - 30; 

文档

Time::Piece拥有出色的文档,您可以在命令行上使用perldoc阅读它。

$ perldoc Time::Piece


这篇文章最初发表在PerlTricks.com上。

标签

David Farrell

David是一位专业的程序员,他经常在推特博客上分享关于代码和编程艺术的见解。

浏览他们的文章

反馈

这篇文章有问题?请通过GitHub打开一个问题或拉取请求来帮助我们。