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
является основным, хорошим и хорошо известным, у него есть тонкости и ограничения, и для более сложной работы я бы рекомендовал всезнающий (и большой и тяжелый) ДатаВремя
perl -MDateTime -wE'
$t = DateTime->now(time_zone => "local")->subtract(hours => 12);
say $t->strftime("%m/%d/%Y %H:%M")'
Я думаю, стоит подчеркнуть, что этот модуль может делать практически все с datetime.
В качестве примечания имейте в виду проблемы, связанные с переходом на летнее время. Между чудесными скачками часов и случайными несуществующими часами могут быть неприятные сюрпризы, хотя и редко (пример).
Вот программа, предоставленная ikegami для проверки перехода на летнее время (08 марта, 2:00 -> 3:00)
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
† Функция с таким именем существует во многих средах и всегда возвращает отформатированную строку.
person
zdim
schedule
07.02.2020