日期范围从开始日期和持续时间

时间:2016-08-05 13:13:01

标签: arrays perl date datetime

这里是新的,也是perl。

我正在尝试编写一个perl脚本来在工作中进行一些数据存档。我们的目录结构按年份分隔一个级别,然后每天/每月分开。

所以,例如:

\2016\1-1
\2016\1-2
....
\2016\12-20
etc...

我正在尝试使这个脚本可用于每个测试(其中一些将来运行),所以我提示用户输入年份,我用它来填充代码中的目录结构。我在月份日期部分遇到了麻烦。

通常测试时间为3-4天。现在我要求用户测试长度,然后减去一个。我这样做是因为从8日开始的4天测试将是8,9,10和11。如果我不减去一个,只是将持续时间添加到开始日期,它将会到达第12个。

我无法弄清楚如何获取开始日期和持续时间,并将该日期范围放入数组中,然后我可以在需要查找/创建存档目录时调用。

理想情况下,我希望让用户输入测试的年份,开始日期和长度,然后创建一个数组,该数组将保存测试所有日期的月 - 日。然后,当我创建/找到所需的目录时,我可以调用这些数组日期。

现在我仍在努力从用户那里获取输入,这就是我所拥有的一切。

情侣说明:我没有可用的每个Perl模块。我一直在使用DateTime,我不能100%确定我可以使用的其他模块。此外,目录结构在月/日期没有前导零(即2-5,而不是02-05)。

这是我到目前为止的输入代码。它给了我今天的开始日期(我需要更改),并根据测试长度给出正确的结束日期。正如你所看到的,我未能在这方面走得很远:

use warnings;

use DateTime;

my @test_dates;

print "What NAS?";
my $NAS = <STDIN>;
chomp($NAS);

print "What is the Multi-Mission mode (ops/nonops)?";
my $MM_Mode = <STDIN>;
chomp($MM_Mode);

print "What is the data mode (ops/sim/tst)?";
my $Data_Mode = <STDIN>;
chomp($Data_Mode);

print "Which spacecraft (NPP/J01)?";
my $sc = <STDIN>;
chomp($sc);

print "What LOM is being cleaned?";
my $LOM = <STDIN>;
chomp($LOM);

print "What MDMZ is being cleaned?";
my $MDMZ = <STDIN>;
chomp($MDMZ);

print "How many days is the test?";
my $Length   = ( <STDIN> - 1 );
my $date     = DateTime->from_epoch( epoch => time );
my $Duration = DateTime::Duration->new( days => $Length );

print "NAS is $NAS\n";
print "Multi-Mission mode is $MM_Mode\n";
print "Data Mode is $Data_Mode\n";
print "LOM is $LOM\n";
print "MDMZ is $MDMZ\n";

printf $date->ymd('/');

print @test_dates;

2 个答案:

答案 0 :(得分:1)

我不认为你在脑海中清楚地知道你需要什么,但这应该有帮助

use strict;
use warnings 'all';

use Time::Piece;
use Time::Seconds 'ONE_DAY';


print 'Enter start date (YYYY-MM-DD): ';
chomp(my $start = <>);
$start = Time::Piece->strptime($start, '%Y-%m-%d');

print 'Enter number of days: ';
chomp(my $duration = <>);

{
    my $end = $start + ONE_DAY * ($duration-1);
    die "Period crosses end of year" if $start->year != $end->year;
}

my $date = $start;

while ( --$duration ) {
    my $dir = $date->strftime('\%Y\%m-%d');
    $dir =~ s/\D\K0+//g;
    print $dir, "\n";
    $date += ONE_DAY;
}

输出

E:\Perl\source>perl date_duration.pl
Enter start date (YYYY-MM-DD): 2016-7-18
Enter number of days: 22
\2016\7-18
\2016\7-19
\2016\7-20
\2016\7-21
\2016\7-22
\2016\7-23
\2016\7-24
\2016\7-25
\2016\7-26
\2016\7-27
\2016\7-28
\2016\7-29
\2016\7-30
\2016\7-31
\2016\8-1
\2016\8-2
\2016\8-3
\2016\8-4
\2016\8-5
\2016\8-6
\2016\8-7

答案 1 :(得分:0)

这是一种使用DateTime的方法。您不需要创建DateTime :: Duration对象,只要您使用日期数学,DateTime就会隐式执行该操作。

use strict;
use warnings 'all';
use DateTime;
use feature 'say';

my $duration = 4;
my ($year, $month, $day) = (2016, 4, 9);
my $start = DateTime->new( year => $year, month => $month, day => $day);

my @dates;
foreach my $i ( 0 .. ( $duration - 1 )) {
    my $date = $start->clone->add( days => $i )->strftime('\%Y\%m-%d');
    $date =~ s/(?<=\D)0+//g;
    push @dates, $date;
}

say for @dates;

我省略了用户输入内容并只设置了一些值。基本上它每天都会构建,创建文件夹名称并将它们放入数组中。

<强>输出

\2016\4-9
\2016\4-10
\2016\4-11
\2016\4-12