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::Piece
для различных вычислений даты и времени.
В то время как Time::Piece
является основным, хорошим и хорошим Известно, что это имеет свои тонкости и ограничения, и для более сложной работы я бы порекомендовал всезнающий (и большой и тяжелый) DateTime
perl -MDateTime -wE'
$t = DateTime->now(time_zone => "local")->subtract(hours => 12);
say $t->strftime("%m/%d/%Y %H:%M")'
Я думаю, что стоит подчеркнуть, что этот модуль может делать практически все с датами.
Как примечание, всегда следует помнить о проблемах, связанных с изменениями в летнее время. Между чудесными скачками часов и случайными несуществующими часами могут быть неприятные сюрпризы, хотя и редко ( пример ).
Вот программа , предоставляемая 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, а в t csh это setenv TZ "America/New_York"; perl test_DST.pl
)
Выход
2020-03-07T23:00:00
2020-03-07T23:00:00
2020-03-07T23:00:00
† Функция с таким именем существует во многих средах и всегда возвращает отформатированную строку.