Это работает для меня.Но я думаю, это потому, что я в Гринвиче, а вы в CET (GMT + 1).
Недостаток в вашем последнем шаге.Вы путаете два понятия - момент времени и продолжительность.
Вы правильно переводите свои два момента времени в числа эпох Unix, а затем вычитаете эти числа, чтобы получить количество секунд между ними.Это число является продолжительностью.И вы хотите преобразовать эту продолжительность в удобочитаемый формат.Использование localtime()
и POSIX::strtime()
не способ сделать это.POSIX::strftime()
и localtime()
имеют дело с точками во времени, а не с продолжительностью.
Число, которое вы получаете, составляет 1200.Передавая это localtime()
, вы говорите: «Каково число эпох, равное 1200, при преобразовании в дату и время в моем местном часовом поясе?»1 200 в 20:00 1 января 1970 года по Гринвичу.Но в вашем местном, во Франкфурте, часовом поясе, сейчас 20 минут первого.Вот почему вы получаете 1:20, а я получаю 0: 20.
Есть несколько способов это исправить.Вы можете выполнить преобразование вручную.
my $duration = 1_200;
my $mins = int($duration/60);
my $secs = $duration % 60;
Или вы можете использовать подходящий модуль обработки даты / времени, например DateTime (вместе со связанным с ним модулем DateTime :: Duration ).
Это может работать, если вы используете timegm()
и gmtime()
вместо timelocal()
и localtime()
- но я действительно не рекомендую этот подход, поскольку он увековечивает путаницу между точками ввремя и продолжительность.
Обновление: Версия с использованием DateTime.
#/usr/bin/perl
use strict;
use warnings;
use DateTime;
use DateTime::Format::Strptime;
my $h_end = '2018.11.12 00:50:00';
my $h_start = '2018.11.12 00:30:00';
my $date_p = DateTime::Format::Strptime->new(
pattern => '%Y.%m.%d %H:%M:%S'
);
my $duration = $date_p->parse_datetime($h_end)
- $date_p->parse_datetime($h_start);
printf '%02d:%02d:%02d', $duration->in_units('hours', 'minutes', 'seconds');