Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разность дат, нид хэлп 
:(
    Опции темы
meridian
Дата 2.2.2007, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



Привет всем!
Есть вот такой модуль, вроде нормально работал до сих пор
но при следующих значениях ерунда получается
$data1=31.01.2007
$data2=02.02.2007
$diff получатся отриц. число

Код

$diff = diffDates( $date1, $date2, "s" );

sub diffDates
{
    my( $date1, $date2, $fmt )= @_;
    my $result;
    my( $day, $hour, $min, $sec);

    use POSIX;

    my( $year1, $month1, $days1, $hours1, $minutes1, $seconds1 ) = ( $date1 =~ /^(\d{4})\-(\d{2})\-(\d{2})\s+(\d{1,2})\:(\d{2})\:(\d{2})$/);    
    my( $year2, $month2, $days2, $hours2, $minutes2, $seconds2 ) = ( $date2 =~ /^(\d{4})\-(\d{2})\-(\d{2})\s+(\d{1,2})\:(\d{2})\:(\d{2})$/);    
    
    $year1 = ( $year1 - 2000 ) + 100;
    $year2 = ( $year2 - 2000 ) + 100;

    $time1 = POSIX::mktime ( $seconds1, $minutes1, $hours1, $days1, $month1, $year1 );
    $time2 = POSIX::mktime ( $seconds1, $minutes2, $hours2, $days2, $month2, $year2 );

    $day =    $time = POSIX::ceil( ( $time2 - $time1 ) / 3600 / 24 );
    $hour = POSIX::ceil( $time2 - $time1 );
    $min = $hour / 60;
    $sec = $min / 60;
    
    if( $fmt eq "s" ) # часы
    {
        $result = sprintf( "%.2f", $sec );
    }
    elsif( $fmt eq "m" ) # минуты
    {
        $result = sprintf( "%.2f", $min );
    }
    elsif( $fmt eq "h" ) # секунды
    {
        $result = sprintf( "%.2f", $hour );
    }
    else # дни
    {
        $result = sprintf( "%.2f", $day );
    }
    
    return $result;
}



Пасибо

Это сообщение отредактировал(а) meridian - 2.2.2007, 13:02
PM   Вверх
amg
Дата 2.2.2007, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Если уж совсем не хочется пользоваться специализированными модулями для работы с датами (Date::Manip, HTTP::Date), то нужно хотя бы преобразовать даты к тому формату, который подразумевает подпрограмма diffDates
Код

s/(\d+)\.(\d+)\.(\d+)/$3-$2-$1 00:00:00/ for ($data1, $data2);
А число действительно получается отрицательное, но, наверно, так и должно быть, т.к. первая дата раньше (меньше) второй.

Это сообщение отредактировал(а) amg - 2.2.2007, 13:48
PM MAIL   Вверх
meridian
Дата 2.2.2007, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



поправочка, даты в таком формате ,т.е. как обрабатывается в пп
31-01-2007 12:19:47  #data1
02-02-2007 11:19:47  #data2

а меньше непонятно почему , т.к. из date2 вычитаем date1 ( если даты одного месяца, то все нормально )


Это сообщение отредактировал(а) meridian - 2.2.2007, 14:37
PM   Вверх
amg
Дата 2.2.2007, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Смотри внимательно подпрограмму: она требует формат "YYYY-MM-DD hh:mm:ss"
И если на неправильный формат даже не ругается, то не пользуйся такой подпрограммой! Есть же отличные модули для этого! Или, в крайнем случае, преобразуй дату:
Код

s/^(\d+)\.(\d+)\.(\d+)/$3-$2-$1/ for ($data1, $data2);


Это сообщение отредактировал(а) amg - 2.2.2007, 14:52
PM MAIL   Вверх
meridian
Дата 2.2.2007, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



С правильным форматом тоже самое
2007-01-31 12:19:47  #data1
2007-02-02 11:19:47  #data2
PM   Вверх
meridian
Дата 2.2.2007, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



Кстате, amq, если использовать Date::Manip,
достаточно будет при 
$date1 = "2007-01-31 12:19:47" 
$date2= "2007-02-02 11:19:47"

использовать $delta = &DateCalc($date1,$date2);

или нужно преобразоват даты ?
PM   Вверх
meridian
Дата 2.2.2007, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 8.11.2005

Репутация: нет
Всего: нет



Вот так сделал проверку дат
получаю разность в секундах

Код


my $sec = cmc_CDEMDate( $date2 ) - cmc_CDEMDate( $date1 );

use Time::Local;
sub cmc_CDEMDate
{
       my( $datetime )= @_;
       my( $year, $month, $days, $hours, $minutes, $seconds ) = ( $datetime =~ /^(\d{4})\-(\d{2})\-(\d{2})\s+(\d{1,2})\:(\d{2})\:(\d{2})$/);
       return( timelocal( $seconds, $minutes, $hours, $days, $month, $year ) );
}
# end cmc_CDEMDate


PM   Вверх
Bulat
Дата 30.6.2007, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



у меня обнаружился маленький косяк вот тут

Код

return( timelocal( $seconds, $minutes, $hours, $days, $month, $year ) );
 

если дата 22.12.2005 00:00:00

Month '12' out of range 0..11 

Как это понимать ??


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
nitr
Дата 30.6.2007, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Bulat, массивы с 0 начинаются ... 0..11 = 12


--------------------
PM   Вверх
Bulat
Дата 30.6.2007, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



nitr, я понимаю что массивы начинаются с нуля, и если дело только в этом, то как-то не красиво получается, если исчисления месяцов начниается с 1, а функция не понимает, что 12 месяц это декабрь.


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
nitr
Дата 30.6.2007, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



return( timelocal( $seconds, $minutes, $hours, $days, $month-1, $year ) );

Добавлено через 45 секунд
я не видел вашей функции, но думаю это вам поможет ;)


--------------------
PM   Вверх
Bulat
Дата 2.7.2007, 07:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



nitr, ну это-то понятно, просто на 31 число он так не реагирует же, вроде с днями все гуд, а вот с месяцами...


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
nitr
Дата 2.7.2007, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Bulat, немного запутали (т.к. тема в теме), покажите функцию и вводимые данные, а то ничего неясно (я про комментарии) ;)


--------------------
PM   Вверх
amg
Дата 2.7.2007, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Bulat, в документации к модулю Time::Local (я полагаю, функция timelocal оттуда?) сказано: 
"The value for the day of the month is the actual day (ie 1..31), while the month is the number of months since January (0..11). This is consistent with the values returned from localtime() and gmtime()."
Т.е. совет nitr'а - правильный (кто бы сомневался smile )

С годом сложнее, но если не нужны даты из далекого прошлого/будущего, то обычный формат YYYY типа 2005 будет восприниматься правильно, как и год, возвращаемый перловскими функциями localtime и gmtime (YYYY-1900).
PM MAIL   Вверх
Bulat
Дата 2.7.2007, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



amg, я ничего не говорю против совета nitr'а. И то что ты привел читал, но не совсем, лично мне понятно почему же месяцы от 0 отсчитываются, хотелось бы узнать причины, почему не с 1. Вот этого я не нашел.  smile 


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0542 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.