What is the optimal way to loop between two dates

2019-01-25 05:38发布

What is the optimal/clearest way to loop between two dates in Perl? There are plenty of modules on CPAN that deal with such matter, but is there any rule of thumb for iterating between two dates?

4条回答
Deceive 欺骗
2楼-- · 2019-01-25 05:54

These days, most people would recommend using DateTime:

use DateTime;   

my $start = DateTime->new(...); # create two DateTime objects
my $end   = DateTime->new(...);

while ($start <= $end) {
    print $start->ymd, "\n";
    $start->add(days => 1);
}
查看更多
仙女界的扛把子
3楼-- · 2019-01-25 06:11

I think the "best" way to do that depends a lot on what you're doing between these two days.

In many cases, a simple for (0..31) loop will suffice.

In other cases, you may wish to use an epoch value, and add/subtract 86400 seconds on each itteration.

In one application I've written, I do exactly this, using a DateTime object that I add one day to for each iteration. This is likely overkill for many applications, though.

查看更多
Rolldiameter
4楼-- · 2019-01-25 06:14

For everything that uses Date manipulation DateTime is probably the best module out there. To get all dates between two dates with your own increment use something like this:

#!/usr/bin/env perl
use strict;
use warnings;
use DateTime;

my $start = DateTime->new(
    day   => 1,
    month => 1,
    year  => 2000,
);

my $stop = DateTime->new(
    day   => 10,
    month => 1,
    year  => 2000,
);


while ( $start->add(days => 1) < $stop ) {
    printf "Date: %s\n", $start->ymd('-');
}

This will output:

Date: 2000-01-02
Date: 2000-01-03
Date: 2000-01-04
Date: 2000-01-05
Date: 2000-01-06
Date: 2000-01-07
Date: 2000-01-08
Date: 2000-01-09
查看更多
可以哭但决不认输i
5楼-- · 2019-01-25 06:18

I'm offering up a Time::Piece solution, because - unlike DateTime it's a core module (as of perl 5.9.5):

#!/usr/bin/env perl

use strict;
use warnings;
use Time::Piece;
use Time::Seconds;

my $FORMAT = '%Y-%m-%d';

my $start = '2016-01-22';
my $end   = '2016-03-11';


my $start_t = Time::Piece->strptime( $start, $FORMAT );
my $end_t   = Time::Piece->strptime( $end,   $FORMAT );

while ( $start_t <= $end_t ) {
   print $start_t ->strftime($FORMAT), "\n";
   $start_t += ONE_DAY;
}

Both Time::Piece and Time::Seconds are core as of perl 5.9.5. The latter is only needed for ONE_DAY - otherwise you can just add 60 * 60 * 24 instead.

This has the advantage of being able to parse fairly arbitrary date formats.

查看更多
登录 后发表回答