内容

名称

Time::Piece - 面向对象的日期时间对象

概要

use Time::Piece;

my $t = localtime;
print "Time is $t\n";
print "Year is ", $t->year, "\n";

描述

此模块用返回对象的实现替换了标准的 localtimegmtime 函数。它以向后兼容的方式执行此操作,因此在 perlfunc 文档中描述的方式使用 localtime/gmtime 仍然会返回您期望的结果。

该模块实际上实现了 Larry Wall 在 perl5-porters 邮件列表中描述的大部分接口,请参见:https://www.nntp.perl.org/group/perl.perl5.porters/2000/01/msg5283.html

用法

导入此模块后,在标量上下文中使用 localtime 或 gmtime 时,您将获得一个 Time::Piece 对象,而不是获得表示日期和时间的普通标量字符串。该对象的字符串化恰好与 localtime 和 gmtime 函数产生相同的效果。还提供了一个 new() 构造函数,它与 localtime() 相同,只是在传递 Time::Piece 对象时,它是一个复制构造函数。对象上提供了以下方法

$t->sec                 # also available as $t->second
$t->min                 # also available as $t->minute
$t->hour                # 24 hour
$t->mday                # also available as $t->day_of_month
$t->mon                 # 1 = January
$t->_mon                # 0 = January
$t->monname             # Feb
$t->month               # same as $t->monname
$t->fullmonth           # February
$t->year                # based at 0 (year 0 AD is, of course 1 BC)
$t->_year               # year minus 1900
$t->yy                  # 2 digit year
$t->wday                # 1 = Sunday
$t->_wday               # 0 = Sunday
$t->day_of_week         # 0 = Sunday
$t->wdayname            # Tue
$t->day                 # same as wdayname
$t->fullday             # Tuesday
$t->yday                # also available as $t->day_of_year, 0 = Jan 01
$t->isdst               # also available as $t->daylight_savings

$t->hms                 # 12:34:56
$t->hms(".")            # 12.34.56
$t->time                # same as $t->hms

$t->ymd                 # 2000-02-29
$t->date                # same as $t->ymd
$t->mdy                 # 02-29-2000
$t->mdy("/")            # 02/29/2000
$t->dmy                 # 29-02-2000
$t->dmy(".")            # 29.02.2000
$t->datetime            # 2000-02-29T12:34:56 (ISO 8601)
$t->cdate               # Tue Feb 29 12:34:56 2000
"$t"                    # same as $t->cdate

$t->epoch               # seconds since the epoch
$t->tzoffset            # timezone offset in a Time::Seconds object

$t->julian_day          # number of days since Julian period began
$t->mjd                 # modified Julian date (JD-2400000.5 days)

$t->week                # week number (ISO 8601)

$t->is_leap_year        # true if it's a leap year
$t->month_last_day      # 28-31

$t->time_separator($s)  # set the default separator (default ":")
$t->date_separator($s)  # set the default separator (default "-")
$t->day_list(@days)     # set the default weekdays
$t->mon_list(@days)     # set the default months

$t->strftime(FORMAT)    # same as POSIX::strftime (without the overhead
                        # of the full POSIX extension)
$t->strftime()          # "Tue, 29 Feb 2000 12:34:56 GMT"

Time::Piece->strptime(STRING, FORMAT)
                        # see strptime man page. Creates a new
                        # Time::Piece object

请注意,上面没有列出 localtimegmtime。如果在 Time::Piece 对象上作为方法调用,它们充当构造函数,返回一个表示当前时间的新的 Time::Piece 对象。换句话说:它们作为方法没有用。

本地语言环境

wdayname(星期几)和 monname(月份)都允许传入一个列表来索引星期几的名称。如果您需要实现某种形式的本地化而无需实际安装或使用语言环境,这将非常有用。请注意,这是一个全局覆盖,将影响所有 Time::Piece 实例。

my @days = qw( Dimanche Lundi Merdi Mercredi Jeudi Vendredi Samedi );

my $french_day = localtime->day(@days);

这些设置也可以在全局范围内覆盖

Time::Piece::day_list(@days);

或用于月份

Time::Piece::mon_list(@months);

以及用于月份的本地设置

print localtime->month(@months);

或者要使用当前系统语言环境填充,请调用:Time::Piece->use_locale();

日期计算

可以使用对象简单的加减法

use Time::Seconds;

my $seconds = $t1 - $t2;
$t1 += ONE_DAY; # add 1 day (constant from Time::Seconds)

以下是有效的($t1 和 $t2 是 Time::Piece 对象)

$t1 - $t2; # returns Time::Seconds object
$t1 - 42; # returns Time::Piece object
$t1 + 533; # returns Time::Piece object

但是,将 Time::Piece 对象添加到另一个 Time::Piece 对象会导致运行时错误。

请注意,上述第一个返回一个 Time::Seconds 对象,因此,虽然检查对象将打印秒数(由于重载),但您还可以使用 Time::Seconds API 获取该增量中的分钟数、小时数、天数、周数和年数。

除了添加秒数之外,还有两个 API 用于添加月份和年份

$t = $t->add_months(6);
$t = $t->add_years(5);

月份和年份可以为负数以进行减法。请注意,在月末添加和减去月份时,有一些“奇怪”的行为。通常,当结果月份比起始月份短时,会添加重叠天数。例如,从 2008-03-31 减去一个月不会得到 2008-02-31,因为这是一个不可能的日期。相反,您将获得 2008-03-02。这似乎与其他日期操作工具一致。

截断

调用 truncate 方法将返回对象的副本,但时间将被截断到提供的单位的开始。

$t = $t->truncate(to => 'day');

此示例将时间设置为与$t之前相同的日期的午夜。 "to"参数的允许值为:"year"、"quarter"、"month"、"day"、"hour"、"minute"和"second"。

日期比较

日期比较也是可能的,使用完整的"<"、">"、"<="、">="、"<=>"、"=="和"!="。

日期解析

Time::Piece有一个内置的strptime()函数(来自FreeBSD),允许你进行非常灵活的日期解析例程。例如

my $t = Time::Piece->strptime("Sunday 3rd Nov, 1943",
                              "%A %drd %b, %Y");

print $t->strftime("%a, %d %b %Y");

输出

Wed, 03 Nov 1943

(看,它甚至足够聪明,可以修复我明显的日期错误)

有关更多信息,请参阅“man strptime”,它应该在所有unix系统上。

或者查看这里:http://www.unix.com/man-page/FreeBSD/3/strftime/

警告 %A、%a、%B、%b 和朋友们

默认情况下,Time::Piece::strptime只能解析美式英语日期名称。同时,Time::Piece->strftime()将返回使用当前配置的系统区域设置的日期名称。这意味着由strftime返回的日期可能无法被strptime解析。这是默认行为,可以通过调用Time::Piece->use_locale()来覆盖。这将构建当前区域设置的星期几和月份名称列表,strptime将使用这些名称进行解析。请注意,这是一个全局覆盖,将影响所有Time::Piece实例。

例如,使用德语区域设置

localtime->day_list();

返回

( 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' )

Time::Piece->use_locale();
localtime->day_list();

返回

( 'So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa' )

YYYY-MM-DDThh:mm:ss

ISO 8601标准将日期格式定义为YYYY-MM-DD,时间格式定义为hh:mm:ss(24小时制),如果组合,它们应该以日期优先,并在时间前面加上大写“T”。

星期数

星期数对于一些读者来说可能是一个未知的概念。ISO 8601标准规定,星期从星期一开始,一年中的第一周是包含1月4日和该年第一个星期四的那一周。换句话说,如果1月的第一个星期一是2日、3日或4日,则1月的前几天属于前一年的最后一周。星期数范围从1到53。

全局覆盖

最后,可以通过在导入列表中包含“:override”标签来覆盖所有地方的localtime和gmtime

use Time::Piece ':override';

警告

在Win32上的线程中设置$ENV{TZ}

请注意,在 Win32 上使用默认构建配置的 Perl(具体来说,当 Perl 使用 PERL_IMPLICIT_SYS 构建时),每个 Perl 解释器都维护其自己的环境副本,并且只有主解释器会更新 strftime 所见的过程环境。

因此,如果您在主线程以外的线程中更改了 $ENV{TZ},那么如果您随后使用 %Z 格式化代码调用 strftime,则 strftime 将不会看到这些更改。您必须在主线程中更改 $ENV{TZ} 才能在这种情况下产生预期的效果(并且您还必须在主线程中调用 _tzset() 以注册环境更改)。

此外,请记住,此警告也适用于 fork(),它在 Win32 上由线程模拟。

使用纪元秒

此模块在内部使用通过 perl time() 函数提供的纪元秒系统,并由 gmtime()localtime() 支持。

如果您的 perl 不支持大于 2^31 秒的时间,则此模块很可能在处理 2038 年之后的日期时失败。perl 中正在努力解决这个问题。或者使用 64 位 perl。或者,如果这些都不是选项,请使用 DateTime 模块,它支持远未来和过去的年份。

此外,Time::Piece->strftime 的内部表示与标准 POSIX 实现不同,因为它使用纪元(而不是单独的年份、月份、日期部分)。此更改是在版本 1.30 中添加的。如果您必须使用更传统的 strftime(通常永远不会正确计算夏令时),您可以将日期部分从 Time::Piece 传递到 POSIX 模块提供的 strftime 函数中(请参阅 POSIX 中的 strftime)。

作者

Matt Sergeant,[email protected] Jarkko Hietaniemi,[email protected](在为核心 perl 创建 Time::Piece 时)

版权和许可

版权所有 2001,Larry Wall。

此模块是自由软件,您可以根据与 Perl 相同的条款分发它。

另请参阅

位于 http://www.tondering.dk/claus/calendar.html 的优秀日历常见问题解答

错误

测试工具还有很多不足之处。欢迎补丁。