Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > Время - localtime, timelocal, mktime + зоны


Автор: Rang 29.4.2010, 16:40
Есть необходимость вычисления временных диапазонов с учетом изменения только дней.
С помощью функции localtime время (количество секунд полученое с помощью функции time) разбивается на переменные (год, месяц, день ...).
Вроде все хорошо, локальная временная зона учтена, данные совпали с показываемыми функцией " > date".

Теперь нужно получить разницу в секундах между текущим временем и временем через месяц.
Используем функцию обратную localtime - timelocal:
Код

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon += 1;
$n_time = timelocal($sec, $min, $hour, $mday, $mon, $year);


Эта функция также отрабатывается без проблем, если мы верно указали количество дней в месяце.
Но если текущее число - 31, и мы пытаемся получить таким же образом следующую дату, в следующем месяце - мы получаем сообщение об ошибке "day out of range 0 .. 31" (или в таком же духе).

В поисках решения, была найдена функция mktime, которая *чхала* на излишек дней и прибавляла их к следующему месяцу.
В итоге получили:
Код

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon += 1;
$n_time = mktime($sec, $min, $hour, $mday, $mon, $year);


Все бы ничего, пока зона не была сменена на родную (отличную от UTC), и появились сдвиги из-за переходов на летнее время.

Теперь mktime упорно возвращает дату с прибавлением лишнего часа. В итоге имеем не "00:00", а "01:00".
Что собственно не приемлемо, и необходимо получить тоже самое значение "00:00".

При попытке изменять передаваемый параметр is_dst в функцию mktime - ничего не меняется.

Как быть?

Писать обвязку для timelocal с использованием mktime, но только для корректировки месяца и дня?

Есть ли какое-то уже готовое решение? Функция?

Автор: vadiml 29.4.2010, 20:25
Time::Piece

Автор: klem4 4.5.2010, 18:41
Судя по тому как поставлена задача, решить ее можно иначе. Но для этого нужно более точно понимать что именно Вы хотите получить. текущий юникстайм + что ?

Автор: Rang 6.5.2010, 15:46
Цитата

Time::Piece

Вещь интересная. Но необходимые функции в нем появились в версии 1.2, которая в свою очередь приспособлена к Перлу 5.10.* (точно не помню=) )
Менять Перл или адаптировать данный скрипт нашел немного нецелесообразным.

На данный момент решаю вопрос так:
Код

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon += 1;
$n_time = mktime($sec, $min, $hour, $mday, $mon, $year);
if($isdst)
{
    $n_time -= 3600; # для нашей временной зоны
}


Цитата

Но для этого нужно более точно понимать что именно Вы хотите получить. текущий юникстайм + что ?

Повнимателней ознакомтесь с первым постом. ;)

Но исходя из развития систем, чую придется уходить от данных принципов работы со временем. :\

Автор: kavkaz 12.6.2010, 04:51
http://search.cpan.org/~stbey/Date-Calc-6.3/lib/Date/Calc.pod смотрели?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)