Time::Piece - 面向对象的日期时间对象
use Time::Piece;
my $t = localtime;
print "Time is $t\n";
print "Year is ", $t->year, "\n";
此模块用返回对象的实现替换了标准的 localtime
和 gmtime
函数。它以向后兼容的方式执行此操作,因此在 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
请注意,上面没有列出 localtime
和 gmtime
。如果在 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/
默认情况下,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' )
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 上使用默认构建配置的 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 的优秀日历常见问题解答
测试工具还有很多不足之处。欢迎补丁。