почему POSIX qw {strftime}; дает мне час на "0" секунд? - PullRequest
1 голос
/ 25 апреля 2020

Я играл с POSIX qw{strftime};, чтобы использовать в качестве времени работы для программы, и я нашел что-то, что я не знал, почему это произошло. Я не использую время так много, это было причиной, по которой я возился с этим (учится заполнять «время»: P) математика дает мне | uptime: 01:00:00, где я должен быть 00:00:00 Я ставлю в строку $stop_secs = $stop_secs - "3600"; и "исправил" это, но мне интересно, откуда взялся этот дополнительный час.

Я понятия не имею, почему, кто-нибудь может объяснить это или почему это происходит? Спасибо.

#!/usr/bin/perl
#
use strict;
use warnings;
use POSIX qw{strftime};


my $start_secs = time();
my $start_time = strftime '%H:%M:%S', localtime $start_secs; # all is: "%Y-%m-%d %H:%M:%S"

my $stop_secs = time();
$stop_secs = $stop_secs - "3600";  #<--- this fix the 1h "bug"? 

my $diff_secs = $stop_secs - $start_secs;
my $diff_time = strftime '%H:%M:%S', localtime $diff_secs;

print " 
    | Time started: $start_time
    | uptime:   $diff_time

\n";

Ответы [ 3 ]

1 голос
/ 26 апреля 2020

time возвращает дату и время (в календаре).

localtime, gmtime и POSIX::strftime предназначены для обработки этих календарных дат, а не временных интервалов.

I рекомендую посмотреть DateTime для дат и DateTime::Span для пролетов.

1 голос
/ 26 апреля 2020

localtime($seconds) возвращает информацию о локальной дате и времени, соответствующую $seconds секундам после полуночи 1 января 1970 года, UT C (1970-01-01T00: 00: 00Z), игнорируя високосные секунды.

Итак, предположим, что машина использует Европу / Париж в качестве часового пояса. Когда было 0 секунд после 1970-01-01T00: 00: 00Z, местное время было бы 1970-01-01T01: 00: 00 + 01: 00. Поэтому на такой машине вы получаете 01:00:00.

#!/usr/bin/perl
use feature qw( say );
use POSIX qw( strftime );
say strftime("%Y-%m-%dT%H:%M:%S%z", localtime(0)) =~ s/(?=..\z)/:/r;
say strftime("           %H:%M:%S", localtime(0));
$ TZ=Europe/Paris ./a
1970-01-01T01:00:00+01:00
           01:00:00

$ TZ=America/Montreal ./a
1969-12-31T19:00:00-05:00
           19:00:00

. Вы не должны использовать localtime. Вы могли бы использовать gmtime в некоторой степени.

#!/usr/bin/perl
use feature qw( say );
use POSIX qw( strftime );
say strftime("%Y-%m-%dT%H:%M:%SZ", gmtime(0));
say strftime("           %H:%M:%S", gmtime(0));
$ TZ=Europe/Paris ./b
1970-01-01T00:00:00Z
           00:00:00

$ TZ=America/Montreal ./b
1970-01-01T00:00:00Z
           00:00:00

Но на самом деле, вы даже не должны использовать strftime, так как это для времени, а не продолжительности. Это будет работать, но только в экстенте.

  • strftime("%H:%M:%S", gmtime($secs)) будет работать в течение, но не включая 24 * 60 * 60 секунд.
  • strftime("%d:%H:%M:%S", gmtime($secs)) будет работать в течение длительностей до, но не включая 31 * 24 * 60 * 60 секунд, если вы можете представлять день как 24 часа.
1 голос
/ 25 апреля 2020

localtime(0) производит информацию о времени в вашем местном часовом поясе на начало эпохи. Если вы не находитесь в том же часовом поясе, что и Гринвич, Англия (а не в летнее время), strftime не будет преобразовывать его в нули. Например, здесь, в Калифорнии, я получаю

$ perl -MPOSIX=strftime -E 'say strftime "%H:%M:%S",localtime(0)'
16:00:00

. Я не знаю, является ли комбинация функций strftime и perl, которая возвращает список информации о времени, правильным инструментом для этого. работу, но если вы собираетесь go таким образом, используйте gmtime вместо localtime.

$ perl -MPOSIX=strftime -E 'say strftime "%H:%M:%S",gmtime(0)'
00:00:00
...