在Perl中两个日期之间循环的最佳/最清晰的方法是什么? CPAN上有很多模块可以解决这个问题,但是在两个日期之间迭代是否有任何经验法则?
答案 0 :(得分:29)
对于使用日期操作的所有内容DateTime
可能是最好的模块。要使用您自己的增量获取两个日期之间的所有日期,请使用以下内容:
#!/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('-');
}
这将输出:
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
答案 1 :(得分:6)
现在,大多数人会建议使用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);
}
答案 2 :(得分:3)
我正在提供一个Time::Piece
解决方案,因为 - 与DateTime
不同,它是一个核心模块(截至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;
}
Time::Piece
和Time::Seconds
都是perl 5.9.5的核心。后者仅在ONE_DAY
时需要 - 否则您只需添加60 * 60 * 24
即可。
这样做的好处是能够解析相当任意的日期格式。
答案 3 :(得分:1)
我认为做到这一点的“最佳”方式很大程度上取决于这两天之间你正在做什么。
在许多情况下,简单的for (0..31)
循环就足够了。
在其他情况下,您可能希望使用纪元值,并在每次迭代时加/减86400秒。
在我编写的一个应用程序中,我正是这样做的,使用我为每次迭代添加一天的DateTime对象。但是,对于许多应用程序而言,这可能有点过头了。
答案 4 :(得分:0)
从2020年开始,另一种选择是使用Time::Moment,它们通过清晰的界面具有非常好的性能(请参阅the benchmarks)。
重新实现Sobrique的答案是:
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Moment;
# Same than 'Y-%m-%d'
my $FORMAT = '%F';
my $start = '2020-01-22';
my $end = '2020-03-11';
my $start_t = Time::Moment->from_string( $start . 'T00Z' );
my $end_t = Time::Moment->from_string( $end . 'T00Z' );
while ( $start_t <= $end_t ) {
print $start_t ->strftime( $FORMAT ), "\n";
$start_t->plus_days( 1 );
}
Time::Moment
不是核心模块,但是如果需要额外的速度,与Time::Piece
和DateTime
相比,它可以有所帮助。另外,该界面非常易于阅读。日期解析功能的限制可能会少一些。