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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Массив дат в интервале 
:(
    Опции темы
rcdimon
Дата 15.12.2006, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 766
Регистрация: 12.7.2004
Где: Москва

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



Всем привет.


Есть две даты 

$date1 = '2006-01-01';
$date2 = '2006-04-20';
к примеру....

необходимо получить массив всех дат в этом интервале, включая крайние...

2006-01-01
2006-01-02
2006-01-03
...
...
...
2006-04-19
2006-04-20


Как сделать?  smile 

заранее благодарен

Добавлено @ 17:40 
Вообще алгоритм может быть прост...

Сначала вычисляем на сколько дней отличается одна дата от другой, наприер на 123, а потом в цикле добавляем к начальному.


PM MAIL ICQ   Вверх
rcdimon
Дата 15.12.2006, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 766
Регистрация: 12.7.2004
Где: Москва

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



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

Одна подпрограмма определяет сколько дней в месяце. Причем она понимает високосные года.

Как узнать високосный год или нет я узнал на Википедии

Код

год является високосным, если он кратен 4 и при этом не кратен 100 либо кратен 400. Год не является високосным, если он кратен 4, но при этом кратен 100 и не кратен 400.


Поэтому получается такая подпрограммка

Код

sub last_day_of_month {
    my $dataref = shift;
    # month
    # year
    # full_date (2006-02-13)

    my ($year, $month);

    if ($dataref->{full_date}){
        my $temp = $dataref->{full_date};
        $temp =~ m/(\d{4})-(\d{1,2})-(\d{1,2})/gm;
        $year = $1;
        $month = $2;
    } else {
        $year = $dataref->{year};
        $month = $dataref->{month};
    }

    if ($month == 1){
        # Январь
        return 31;
    } elsif ($month == 2){
        # Февраль
        # Проверка на високосный год

        if ((!($year % 4)) and (($year % 100) or (!($year % 400)))){
            return 29;
        }
        return 28;
    } elsif ($month == 3){
        # Март
        return 31;
    } elsif ($month == 4){
        # Апрель
        return 30;
    } elsif ($month == 5){
        # Май
        return 31;
    } elsif ($month == 6){
        # Июнь
        return 30;
    } elsif ($month == 7){
        # Июль
        return 31;
    } elsif ($month == 8){
        # Август
        return 31;
    } elsif ($month == 9){
        # Сентябрь
        return 30;
    } elsif ($month == 10){
        # Октябрь
        return 31;
    } elsif ($month == 11){
        # Ноябрь
        return 30;
    } elsif ($month == 12){
        # Декабрь
        return 31;
    }
}


потом я решил написать функцию, которая принимает в качестве параметра дату, а возвращает дату следующего дня

Код

sub inc_date {
    my $dataref = shift;
    #
    # day
    # month
    # year
    # fulldate
    
    my ($year,$month,$day);
    
    if ($dataref->{full_date}){
        my $temp = $dataref->{full_date};
        $temp =~ m/(\d{4})-(\d{1,2})-(\d{1,2})/gm;
        
        $year    = $1;
        $month   = $2;
        $day     = $3;
    } else {
        $year    = $dataref->{year};
        $month   = $dataref->{month};
        $day     = $dataref->{day};
    }
    
    $day++;
    
    if ($day > last_day_of_month({year => $year, month => $month})){
        # Месяц переполнился
        $day = '01';
        $month++;
        if ($month > 12){
            $year++;
            $month = '01';
        }
    }
    
    return $year . '-' . $month . '-' . $day;
}



ну и код основной программы, проще некуда

Код

my $date1 = '2001-01-01';
my $date2 = '2003-04-23';
my $date = $date1;
my @date_mass;
push @date_mass, $date1; 

while ($date ne $date2){
$date = inc_date({ full_date => $date});
   push @date_mass, $date; 
}

print join("\n",@date_mass);



тут правда кроется небольшая опасность. Например если $date2 вообще не является датой, а любой другой сторокой то программа зациклится... А еще она зациклится если $date2 меньше чем $date1... Но это уже другой разговор

результат

Код

2001-01-01
2001-01-02
2001-01-03
2001-01-04
2001-01-05
2001-01-06
2001-01-07
2001-01-08
2001-01-09
2001-01-10
2001-01-11
2001-01-12
2001-01-13
2001-01-14
2001-01-15
2001-01-16
2001-01-17
2001-01-18
2001-01-19
2001-01-20
2001-01-21
2001-01-22
2001-01-23
2001-01-24
2001-01-25
2001-01-26
2001-01-27
2001-01-28
2001-01-29
2001-01-30
2001-01-31
2001-02-01
2001-02-02
2001-02-03
2001-02-04
2001-02-05
2001-02-06
2001-02-07
2001-02-08
2001-02-09
2001-02-10
2001-02-11
2001-02-12
2001-02-13
2001-02-14
2001-02-15
2001-02-16
2001-02-17
2001-02-18
2001-02-19
2001-02-20
2001-02-21
2001-02-22
2001-02-23
2001-02-24
2001-02-25
2001-02-26
2001-02-27
2001-02-28
2001-03-01
2001-03-02
2001-03-03
2001-03-04
2001-03-05
2001-03-06
2001-03-07
2001-03-08
2001-03-09
2001-03-10
2001-03-11
2001-03-12
2001-03-13
2001-03-14
2001-03-15
2001-03-16
2001-03-17
2001-03-18
2001-03-19
2001-03-20
2001-03-21
2001-03-22
2001-03-23
2001-03-24
2001-03-25
2001-03-26
2001-03-27
2001-03-28
2001-03-29
2001-03-30
2001-03-31
2001-04-01
2001-04-02
2001-04-03
2001-04-04
2001-04-05
2001-04-06
2001-04-07
2001-04-08
2001-04-09
2001-04-10
2001-04-11
2001-04-12
2001-04-13
2001-04-14
2001-04-15
2001-04-16
2001-04-17
2001-04-18
2001-04-19
2001-04-20
2001-04-21
2001-04-22
2001-04-23
2001-04-24
2001-04-25
2001-04-26
2001-04-27
2001-04-28
2001-04-29
2001-04-30
2001-05-01
2001-05-02
2001-05-03
2001-05-04
2001-05-05
2001-05-06
2001-05-07
2001-05-08
2001-05-09
2001-05-10
2001-05-11
2001-05-12
2001-05-13
2001-05-14
2001-05-15
2001-05-16
2001-05-17
2001-05-18
2001-05-19
2001-05-20
2001-05-21
2001-05-22
2001-05-23
2001-05-24
2001-05-25
2001-05-26
2001-05-27
2001-05-28
2001-05-29
2001-05-30
2001-05-31
2001-06-01
2001-06-02
2001-06-03
2001-06-04
2001-06-05
2001-06-06
2001-06-07
2001-06-08
2001-06-09
2001-06-10
2001-06-11
2001-06-12
2001-06-13
2001-06-14
2001-06-15
2001-06-16
2001-06-17
2001-06-18
2001-06-19
2001-06-20
2001-06-21
2001-06-22
2001-06-23
2001-06-24
2001-06-25
2001-06-26
2001-06-27
2001-06-28
2001-06-29
2001-06-30
2001-07-01
2001-07-02
2001-07-03
2001-07-04
2001-07-05
2001-07-06
2001-07-07
2001-07-08
2001-07-09
2001-07-10
2001-07-11
2001-07-12
2001-07-13
2001-07-14
2001-07-15
2001-07-16
2001-07-17
2001-07-18
2001-07-19
2001-07-20
2001-07-21
2001-07-22
2001-07-23
2001-07-24
2001-07-25
2001-07-26
2001-07-27
2001-07-28
2001-07-29
2001-07-30
2001-07-31
2001-08-01
2001-08-02
2001-08-03
2001-08-04
2001-08-05
2001-08-06
2001-08-07
2001-08-08
2001-08-09
2001-08-10
2001-08-11
2001-08-12
2001-08-13
2001-08-14
2001-08-15
2001-08-16
2001-08-17
2001-08-18
2001-08-19
2001-08-20
2001-08-21
2001-08-22
2001-08-23
2001-08-24
2001-08-25
2001-08-26
2001-08-27
2001-08-28
2001-08-29
2001-08-30
2001-08-31
2001-09-01
2001-09-02
2001-09-03
2001-09-04
2001-09-05
2001-09-06
2001-09-07
2001-09-08
2001-09-09
2001-09-10
2001-09-11
2001-09-12
2001-09-13
2001-09-14
2001-09-15
2001-09-16
2001-09-17
2001-09-18
2001-09-19
2001-09-20
2001-09-21
2001-09-22
2001-09-23
2001-09-24
2001-09-25
2001-09-26
2001-09-27
2001-09-28
2001-09-29
2001-09-30
2001-10-01
2001-10-02
2001-10-03
2001-10-04
2001-10-05
2001-10-06
2001-10-07
2001-10-08
2001-10-09
2001-10-10
2001-10-11
2001-10-12
2001-10-13
2001-10-14
2001-10-15
2001-10-16
2001-10-17
2001-10-18
2001-10-19
2001-10-20
2001-10-21
2001-10-22
2001-10-23
2001-10-24
2001-10-25
2001-10-26
2001-10-27
2001-10-28
2001-10-29
2001-10-30
2001-10-31
2001-11-01
2001-11-02
2001-11-03
2001-11-04
2001-11-05
2001-11-06
2001-11-07
2001-11-08
2001-11-09
2001-11-10
2001-11-11
2001-11-12
2001-11-13
2001-11-14
2001-11-15
2001-11-16
2001-11-17
2001-11-18
2001-11-19
2001-11-20
2001-11-21
2001-11-22
2001-11-23
2001-11-24
2001-11-25
2001-11-26
2001-11-27
2001-11-28
2001-11-29
2001-11-30
2001-12-01
2001-12-02
2001-12-03
2001-12-04
2001-12-05
2001-12-06
2001-12-07
2001-12-08
2001-12-09
2001-12-10
2001-12-11
2001-12-12
2001-12-13
2001-12-14
2001-12-15
2001-12-16
2001-12-17
2001-12-18
2001-12-19
2001-12-20
2001-12-21
2001-12-22
2001-12-23
2001-12-24
2001-12-25
2001-12-26
2001-12-27
2001-12-28
2001-12-29
2001-12-30
2001-12-31
2002-01-01
2002-01-02
2002-01-03
2002-01-04
2002-01-05
2002-01-06
2002-01-07
2002-01-08
2002-01-09
2002-01-10
2002-01-11
2002-01-12
2002-01-13
2002-01-14
2002-01-15
2002-01-16
2002-01-17
2002-01-18
2002-01-19
2002-01-20
2002-01-21
2002-01-22
2002-01-23
2002-01-24
2002-01-25
2002-01-26
2002-01-27
2002-01-28
2002-01-29
2002-01-30
2002-01-31
2002-02-01
2002-02-02
2002-02-03
2002-02-04
2002-02-05
2002-02-06
2002-02-07
2002-02-08
2002-02-09
2002-02-10
2002-02-11
2002-02-12
2002-02-13
2002-02-14
2002-02-15
2002-02-16
2002-02-17
2002-02-18
2002-02-19
2002-02-20
2002-02-21
2002-02-22
2002-02-23
2002-02-24
2002-02-25
2002-02-26
2002-02-27
2002-02-28
2002-03-01
2002-03-02
2002-03-03
2002-03-04
2002-03-05
2002-03-06
2002-03-07
2002-03-08
2002-03-09
2002-03-10
2002-03-11
2002-03-12
2002-03-13
2002-03-14
2002-03-15
2002-03-16
2002-03-17
2002-03-18
2002-03-19
2002-03-20
2002-03-21
2002-03-22
2002-03-23
2002-03-24
2002-03-25
2002-03-26
2002-03-27
2002-03-28
2002-03-29
2002-03-30
2002-03-31
2002-04-01
2002-04-02
2002-04-03
2002-04-04
2002-04-05
2002-04-06
2002-04-07
2002-04-08
2002-04-09
2002-04-10
2002-04-11
2002-04-12
2002-04-13
2002-04-14
2002-04-15
2002-04-16
2002-04-17
2002-04-18
2002-04-19
2002-04-20
2002-04-21
2002-04-22
2002-04-23
2002-04-24
2002-04-25
2002-04-26
2002-04-27
2002-04-28
2002-04-29
2002-04-30
2002-05-01
2002-05-02
2002-05-03
2002-05-04
2002-05-05
2002-05-06
2002-05-07
2002-05-08
2002-05-09
2002-05-10
2002-05-11
2002-05-12
2002-05-13
2002-05-14
2002-05-15
2002-05-16
2002-05-17
2002-05-18
2002-05-19
2002-05-20
2002-05-21
2002-05-22
2002-05-23
2002-05-24
2002-05-25
2002-05-26
2002-05-27
2002-05-28
2002-05-29
2002-05-30
2002-05-31
2002-06-01
2002-06-02
2002-06-03
2002-06-04
2002-06-05
2002-06-06
2002-06-07
2002-06-08
2002-06-09
2002-06-10
2002-06-11
2002-06-12
2002-06-13
2002-06-14
2002-06-15
2002-06-16
2002-06-17
2002-06-18
2002-06-19
2002-06-20
2002-06-21
2002-06-22
2002-06-23
2002-06-24
2002-06-25
2002-06-26
2002-06-27
2002-06-28
2002-06-29
2002-06-30
2002-07-01
2002-07-02
2002-07-03
2002-07-04
2002-07-05
2002-07-06
2002-07-07
2002-07-08
2002-07-09
2002-07-10
2002-07-11
2002-07-12
2002-07-13
2002-07-14
2002-07-15
2002-07-16
2002-07-17
2002-07-18
2002-07-19
2002-07-20
2002-07-21
2002-07-22
2002-07-23
2002-07-24
2002-07-25
2002-07-26
2002-07-27
2002-07-28
2002-07-29
2002-07-30
2002-07-31
2002-08-01
2002-08-02
2002-08-03
2002-08-04
2002-08-05
2002-08-06
2002-08-07
2002-08-08
2002-08-09
2002-08-10
2002-08-11
2002-08-12
2002-08-13
2002-08-14
2002-08-15
2002-08-16
2002-08-17
2002-08-18
2002-08-19
2002-08-20
2002-08-21
2002-08-22
2002-08-23
2002-08-24
2002-08-25
2002-08-26
2002-08-27
2002-08-28
2002-08-29
2002-08-30
2002-08-31
2002-09-01
2002-09-02
2002-09-03
2002-09-04
2002-09-05
2002-09-06
2002-09-07
2002-09-08
2002-09-09
2002-09-10
2002-09-11
2002-09-12
2002-09-13
2002-09-14
2002-09-15
2002-09-16
2002-09-17
2002-09-18
2002-09-19
2002-09-20
2002-09-21
2002-09-22
2002-09-23
2002-09-24
2002-09-25
2002-09-26
2002-09-27
2002-09-28
2002-09-29
2002-09-30
2002-10-01
2002-10-02
2002-10-03
2002-10-04
2002-10-05
2002-10-06
2002-10-07
2002-10-08
2002-10-09
2002-10-10
2002-10-11
2002-10-12
2002-10-13
2002-10-14
2002-10-15
2002-10-16
2002-10-17
2002-10-18
2002-10-19
2002-10-20
2002-10-21
2002-10-22
2002-10-23
2002-10-24
2002-10-25
2002-10-26
2002-10-27
2002-10-28
2002-10-29
2002-10-30
2002-10-31
2002-11-01
2002-11-02
2002-11-03
2002-11-04
2002-11-05
2002-11-06
2002-11-07
2002-11-08
2002-11-09
2002-11-10
2002-11-11
2002-11-12
2002-11-13
2002-11-14
2002-11-15
2002-11-16
2002-11-17
2002-11-18
2002-11-19
2002-11-20
2002-11-21
2002-11-22
2002-11-23
2002-11-24
2002-11-25
2002-11-26
2002-11-27
2002-11-28
2002-11-29
2002-11-30
2002-12-01
2002-12-02
2002-12-03
2002-12-04
2002-12-05
2002-12-06
2002-12-07
2002-12-08
2002-12-09
2002-12-10
2002-12-11
2002-12-12
2002-12-13
2002-12-14
2002-12-15
2002-12-16
2002-12-17
2002-12-18
2002-12-19
2002-12-20
2002-12-21
2002-12-22
2002-12-23
2002-12-24
2002-12-25
2002-12-26
2002-12-27
2002-12-28
2002-12-29
2002-12-30
2002-12-31
2003-01-01
2003-01-02
2003-01-03
2003-01-04
2003-01-05
2003-01-06
2003-01-07
2003-01-08
2003-01-09
2003-01-10
2003-01-11
2003-01-12
2003-01-13
2003-01-14
2003-01-15
2003-01-16
2003-01-17
2003-01-18
2003-01-19
2003-01-20
2003-01-21
2003-01-22
2003-01-23
2003-01-24
2003-01-25
2003-01-26
2003-01-27
2003-01-28
2003-01-29
2003-01-30
2003-01-31
2003-02-01
2003-02-02
2003-02-03
2003-02-04
2003-02-05
2003-02-06
2003-02-07
2003-02-08
2003-02-09
2003-02-10
2003-02-11
2003-02-12
2003-02-13
2003-02-14
2003-02-15
2003-02-16
2003-02-17
2003-02-18
2003-02-19
2003-02-20
2003-02-21
2003-02-22
2003-02-23
2003-02-24
2003-02-25
2003-02-26
2003-02-27
2003-02-28
2003-03-01
2003-03-02
2003-03-03
2003-03-04
2003-03-05
2003-03-06
2003-03-07
2003-03-08
2003-03-09
2003-03-10
2003-03-11
2003-03-12
2003-03-13
2003-03-14
2003-03-15
2003-03-16
2003-03-17
2003-03-18
2003-03-19
2003-03-20
2003-03-21
2003-03-22
2003-03-23
2003-03-24
2003-03-25
2003-03-26
2003-03-27
2003-03-28
2003-03-29
2003-03-30
2003-03-31
2003-04-01
2003-04-02
2003-04-03
2003-04-04
2003-04-05
2003-04-06
2003-04-07
2003-04-08
2003-04-09
2003-04-10
2003-04-11
2003-04-12
2003-04-13
2003-04-14
2003-04-15
2003-04-16
2003-04-17
2003-04-18
2003-04-19
2003-04-20
2003-04-21
2003-04-22
2003-04-23


Это сообщение отредактировал(а) rcdimon - 15.12.2006, 21:59
PM MAIL ICQ   Вверх
rcdimon
Дата 15.12.2006, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 766
Регистрация: 12.7.2004
Где: Москва

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



кстати не в оффтоп будет сказано, тут написать еще и валидатор дат... формата YYYY-MM-DD.... Можно конечно напистаь еще функцию, которая понимает кучу других форматов, но сейчас это мне уже не нужно. потому что в программе используется именно такой формат. И любой другой ошибочный

Код

sub date_validator {
    my $dataref = shift;
    # full_date
    
    my $date = $dataref->{full_date};
    if ($date =~ m/(\d{4})-(\d{1,2})-(\d{1,2})/gm){
        if (($2 > 0 and $2 < 13) and ($3 > 0 and $3 <= last_day_of_month({month => $2, year => $1}))){
            return 1;
        }
    }
    return 0;
}

PM MAIL ICQ   Вверх
arto
Дата 16.12.2006, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



use Date::Local;
use POSIX qw(strftime);

sub date_interval ($$) {
  my ($b,$e) = ([split "-",$_[0]],[split "-",$_[1]]);
  my ($bb,$ee) = (timelocal (0,0,0,$b->[2],$b->[1]-1,$b->[0]-1900),
                             timelocal (0,0,0,$e->[2],$e->[1]-1,$e->[0]-1900));
  my @ret;
  for (;$bb <= $ee; $bb += 24*60*60) {
    push @ret,strftime "%Y-%m-%d",localtime ($bb);
  }
  return @ret;
}
PM MAIL ICQ   Вверх
rcdimon
Дата 16.12.2006, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 766
Регистрация: 12.7.2004
Где: Москва

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



Какое ужасть... Мне мое больше нравится  smile 
PM MAIL ICQ   Вверх
korob2001
Дата 16.12.2006, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



rcdimon - вот ещё, как вариант.  smile Как ручной, так и с модулем.
http://forum.vingrad.ru/topic-90892/hl/date/index.html


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
rcdimon
Дата 16.12.2006, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 766
Регистрация: 12.7.2004
Где: Москва

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



Гы. сорьки не искал.. Не думал что у кого-то могла возникнуть такая же задача... Только вот непонятно зачем такой сложный и непонятный код в "ручном" методе? Ведь тут все так просто )
PM MAIL ICQ   Вверх
korob2001
Дата 17.12.2006, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



Цитата(rcdimon @  16.12.2006,  20:12 Найти цитируемый пост)
Только вот непонятно зачем такой сложный и непонятный код в "ручном" методе? Ведь тут все так просто )

Работает он быстрее.  smile  Хотя в данном случае скорость не так критична. Редко тебе понадобится выводить интервалы скажем от 1100 года, до 2007.
У меня, с таким интервалом, твой вариант работает на 6 секунд медленнее.

Это сообщение отредактировал(а) korob2001 - 17.12.2006, 11:08


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


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

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


 




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


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

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