Perl Localtime возвращает 16 часов, когда ввод только секунд

Я должно быть делаю что-то не так, но я не могу понять это. Когда я передаю секунды в качестве аргумента функции localtime(), я получаю секунды и 16 часов назад.

my $startTime = time;

(process)

my $endTime = time;

my $diffTime = ( $endTime - $startTime );

($sec,$min,$hour) = localtime( $diffTime );

print STDERR "diffTime = $diffTime\n";
print STDERR "hour = $hour\n";
print STDERR "min= $min\n";
print STDERR "sec = $sec\n";

print( sprintf( "Elapsed time : %02d:%02d:%02d\n", $hour, $min, $sec ) );

... всегда печатает:

diffTime = 4
hour = 16
min= 0
sec = 4
Elapsed time : 16:00:04

ХОРОШО. Разобрался как добавлять комментарии - настройки NoScript были слишком жесткими.

Спасибо...

Кажется, я не могу добавлять комментарии в эту тему, поэтому я просто поблагодарю всех здесь.

НЕ использование gmtime было проблемой. Это может быть не самое эффективное решение, но оно работает для того, что мне нужно, а это просто небольшая информация для пользователя, чтобы оценить, как долго он / она может ждать завершения процедуры, и принять решение о том, насколько велик ввод. набор данных, с которым ему / ей удобно.


person mmrtnt    schedule 20.01.2011    source источник
comment
Ну, ты случайно не по Гринвичу, не так ли? В противном случае вы увидите сдвиг в зависимости от вашего местного часового пояса.   -  person Piskvor left the building    schedule 20.01.2011


Ответы (4)


Вы смешиваете продолжительность и временные метки, это напрашивается на неприятности... Вы можете обойтись без использования gmtime, как предлагает Мансур, но тем не менее вы используете яблоко вместо апельсина.

Следующее работает и использует основные Time::Piece и Time::Seconds. Однако для $diffTime->pretty вам потребуется более новая версия (1.20) Time::Piece, чем те, что поставляются в комплекте с текущими версиями Perl.

use strict;
use warnings;
use 5.010;
use Time::Piece 1.20;

my $startTime = localtime();

# (process)

my $endTime = localtime();

my $diffTime = ( $endTime - $startTime );

say STDERR "diffTime = ", $diffTime;
say STDERR "hours = ", $diffTime->hours;      # not the same thing as above
say STDERR "minutes = ", $diffTime->minutes;  # not the same thing as above
say STDERR "seconds = ", $diffTime->seconds;  # not the same thing as above

say "Elapsed time: ", $diffTime->pretty;

Это может напечатать что-то вроде:

150
0.0416666666666667
2.5
150
2 minutes, 30 seconds
person mscha    schedule 20.01.2011
comment
Часть, которую вы можете сойти с рук, неверна. Остальное правильно. - person tchrist; 20.01.2011
comment
@tchrist: почему бы ему это не сойти с рук? Пока его процесс не займет более 86400 секунд, он получит ожидаемый результат, не так ли? - person mscha; 20.01.2011
comment
Я очень ценю все ответы здесь, и я надеюсь, что смогу дать некоторые ответы в будущем. - person mmrtnt; 20.01.2011
comment
Прошедшее время никогда не должно включать что-то вроде 1970 или 2010, и делать вид, что его нет в возвращаемых значениях gmtime и localtime, обманчиво и вводит в заблуждение. Это все равно что сказать, что использование сложения вместо возведения в степень для 2**2 «может» помочь получить правильный ответ. - person tchrist; 20.01.2011

$difftime – это разница между двумя "эпохами" (секундами с полуночи по Гринвичу 01.01.1970), но это не делает их эпохой. Так что это не совсем подходящий аргумент для localtime(). Вам лучше вычислить разбивку h/m/s самостоятельно:

($sec,$min,$hour) = ($difftime % 60, int($difftime/60) % 60, int($difftime/3600));
person mob    schedule 20.01.2011
comment
Это, пожалуй, лучшее решение. Я понимаю, что использование gimtime - это глупо. - person mmrtnt; 20.01.2011

Вы хотите использовать функцию gmtime вместо функции localtime.

Поскольку дата эпохи — 1 января 1970 г., 00:00:00 GMT/UTC, по телефону localtime(0) вы получите дату эпохи в вашем часовом поясе.

РЕДАКТИРОВАТЬ: Спасибо за последующие действия. Как уже упоминалось, это работает, только если вы измеряете интервал менее 24 часов. Обе функции localtime и gmtime на самом деле возвращают значения даты: секунды, минуты, часы, день месяца, месяц, год, день года и попадает ли время на летнее время. Конечно, все, кроме секунд, минут и часов, не имеет смысла вне контекста даты.

person Mansoor Siddiqui    schedule 20.01.2011
comment
Это не ответ на вопрос. - person tchrist; 20.01.2011
comment
tchrist: Вы хотите сказать, что переход на gmtime не решит проблему? Я думаю, что это должно работать нормально, пока промежуток времени меньше месяца. - person Gabe; 20.01.2011
comment
($sec,$min,$hour)=gmtime($difftime) работает, но только случайно. - person mob; 20.01.2011

Это та же проблема, что и утверждение, что, поскольку ℉ → ℃ требует преобразования C = (F - 32) * 5/9, то, если стало теплее на 5 ℉, это должно быть то же самое, что потепление на -15 ℃, поскольку это число, которое вы получаете, когда просто подключаете 5 ℉ в очевидную, но неправильную формулу.

Видите, почему это не имеет смысла? Потеплеть на 5 ℉ совсем не то же самое, что похолодать на 15 ℃!

Вы сделали почти ту же ошибку со своим временем. Когда вы вычитаете количество секунд, прошедших с эпохи, вы не получаете результат, который также измеряет секунды, прошедшие с эпохи!!

Вы можете вызывать localtime или gmtime только в секундах эпохи, то есть в секундах, прошедших с эпохи, а не в секундах вообще. В противном случае вы должны выполнить собственное деление или использовать модуль, чтобы узнать, сколько более крупных единиц получается в результате этого вычитания.

person tchrist    schedule 20.01.2011
comment
Хотя я согласен с вами в принципе, чтобы возразить против, но это работает, требуется контрпример. - person ysth; 20.01.2011
comment
Контрпримером является любая задача, которая занимает 86400 и более секунд. - person mob; 21.01.2011