Как перебрать диапазон дат? - PullRequest
4 голосов
/ 16 августа 2010

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

Ответы [ 7 ]

5 голосов
/ 16 августа 2010

Использовать DateTime модуль.Вот простой пример, в котором перечислены десять предыдущих дней:

use 5.012;
use warnings;
use DateTime;

my $end = DateTime->now;
my $day = $end->clone->subtract( days => 10 );  # ten days ago

while ($day < $end) {
    say $day;
    $day->add( days => 1 );   # move along to next day
}

Обновление (после просмотра вашего комментария / обновления):

Дляпроанализируйте строку даты, затем посмотрите на DateTime::Format на модулях CPAN.

Вот пример использования DateTime::Format::DateParse, который выполняет синтаксический анализ YYYY / MM / DD:

use DateTime::Format::DateParse;
my $d = DateTime::Format::DateParse->parse_datetime( '2010/06/23' );
4 голосов
/ 16 августа 2010

Одним из простых подходов является использование модуля Date::Simple, который использует перегрузку оператора:

use strict;
use warnings;
use Date::Simple;

my $date    = Date::Simple->new ( '2010-01-01' );  # Stores Date::Simple object
my $endDate = Date::Simple->today;                 # Today's date

while ( ++$date < $endDate ) {

    print ( $date - $endDate ) , "day",
          ( ( $date-$endDate) == 1 ? '' : 's' ), " ago\n";
}
3 голосов
/ 16 августа 2010
use DateTime::Format::Strptime qw();
my $start = DateTime::Format::Strptime->new(pattern => '%Y/%m/%d')->parse_datetime('2010/08/16');
my $end   = DateTime::Format::Strptime->new(pattern => '%Y/%m/%d')->parse_datetime('2010/11/24');

while ($start < $end) {
    $start->add(days => 1);
    say $start->ymd('/');
}
2 голосов
/ 16 августа 2010

Мне нравится использовать тот факт, что strftime нормализует дату для меня:

#!/usr/bin/perl

use strict;
use warnings;

use POSIX qw/strftime/;

my $start = "2010/08/16";
my $end   = "2010/09/16";

my @time        = (0, 0, 0);
my ($y, $m, $d) = split "/", $start;
$y -= 1900;
$m--;
my $offset      = 0;

while ((my $date = strftime "%Y/%m/%d", @time, $d + $offset, $m, $y) le $end) { 
    print "$date\n";
} continue {
    $offset++;
}
0 голосов
/ 13 января 2014

Если установка дополнительных модулей Perl не является предпочтительной, можно использовать этот подход на основе базовой библиотеки Perl POSIX :

#!/usr/bin/perl

use strict;
use warnings;
use POSIX qw(strftime);

# CREATE CALENDAR
my @Calendar = ();
my $years = 3;
my @Now = localtime(); # An array of 9 date-time parameters.

for my $count ( 0 .. ( 365 * $years ) ) {
    # If date is January 1st, manual shift to December 31st is needed,
    # because days ([yday][2]) are counted from January 31st and never shift back one year.
    if( $Now[4] == 0 && $Now[3] == 1 ) {
        unshift @Calendar, strftime( "%Y-%m-%d", @Now );
        $Now[5] --; # Reduce by one the sixth array element #5 - year.
        $Now[4] = 11; # Set fifth array element № 4 - to December.
        $Now[3] = 31; # Set fourth array element № 3 - to 31st.
    } else {
        unshift @Calendar, strftime( "%Y-%m-%d", @Now );
        $Now[3] --;
    }
}

# Print out.
my $size = @Calendar;
for (my $i = 0; $i < $size; $i++) {
    print $Calendar[$i]."\n";
}
0 голосов
/ 16 августа 2010

Вы можете попробовать Дата :: Calc :: Итератор

  # This puts all the dates from Dec 1, 2003 to Dec 10, 2003 in @dates1
  # @dates1 will contain ([2003,12,1],[2003,12,2] ... [2003,12,10]) ;
  my $i1 = Date::Calc::Iterator->new(from => [2003,12,1], to => [2003,12,10]) ;
  my @dates1 ;
  push @dates1,$_ while $_ = $i1->next ;
0 голосов
/ 16 августа 2010

Perl имеет богатый массив модулей манипуляции с датой и временем, как показано здесь:

http://datetime.perl.org/?Modules

И здесь есть несколько примеров проблем с датой и временем.

С Perl всегда есть несколько способов сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...