POSIX 的strftime
返回字符串。
而且您不能方便地从字符串中减去小时数。†
改为使用库进行日期时间处理以进行操作,然后使用strftime进行格式化
Time::Piece 的示例
perl -MTime::Piece -MTime::Seconds -wE'
$t = (localtime) - 12*ONE_HOUR;
say $t->strftime("%m/%d/%Y %H:%M")'
Time::Seconds 与 Time::Piece 一起提供,用于各种日期时间计算。
虽然Time::Piece 是核心、优秀且众所周知,但它确实存在微妙之处和局限性,对于更多涉及的工作,我推荐无所不知(而且又大又重)DateTime
perl -MDateTime -wE'
$t = DateTime->now(time_zone => "local")->subtract(hours => 12);
say $t->strftime("%m/%d/%Y %H:%M")'
我认为值得强调的是,这个模块几乎可以用日期时间做所有事情。
作为说明,请记住夏令时更改带来的问题。在时钟奇迹般的跳跃和偶尔不存在的时间之间可能会有不愉快的惊喜,尽管很少 (an example)。
这是ikegami 编写的provided 程序,用于测试coming DST(3 月 8 日凌晨 2 点 -> 凌晨 3 点)
use strict;
use warnings;
use DateTime qw( );
use POSIX qw( strftime );
use Time::Piece qw( localtime );
use Time::Seconds qw( ONE_HOUR );
my $epoch = 1583683200; # 2020-03-08T12:00:00
CORE::say
for
DateTime->from_epoch( epoch => $epoch, time_zone => $ENV{TZ} )
->subtract( hours => 12 ),
strftime("%FT%T", localtime($epoch - 12*60*60)),
( localtime($epoch) - 12*ONE_HOUR )->strftime("%FT%T");
然后设置TZ环境变量并运行
TZ=America/New_York perl test_DST.pl
(在 bash 中,在 tcsh 中为 setenv TZ "America/New_York"; perl test_DST.pl)
输出
2020-03-07T23:00:00
2020-03-07T23:00:00
2020-03-07T23:00:00
† 具有该名称的函数存在于许多环境中,并且始终返回格式化字符串。