Reputation: 23
New here, and to perl as well.
I'm trying to write a perl script to do some data archiving at work. Our directory structure is separated at one level by year, then has every day/month inside that.
So, for example:
\2016\1-1
\2016\1-2
....
\2016\12-20
etc...
I'm trying to make this script usable for every test (some of which are run in the future), so I have a prompt for the user to enter the year, which I use to populate the directory structure in the code. I'm having trouble with the month-date portion.
Usually tests are 3-4 days long. Right now I'm asking the user for the test length, then subtracting one. I do that because a 4 day test starting on the 8th, would be the 8 ,9 ,10, and 11th. If I don't subtract one, and just add the duration to the start date, it would go to the 12th.
I can't figure out how to take a start date and duration, and get that range of dates into an array, that I can then call when I need to find/create directories for the archiving.
Ideally, I'd like to have the user enter the year, start date, and length of the test, then create an array that will hold the month-day for all dates of the test. Then I could call those array dates when I create/find the needed directories.
Right now I'm still working on getting the inputs from the user, so that is all that I have.
Couple notes: I don't have every Perl module available to me. I have been using DateTime
, and I'm not 100% sure what other modules I could use. Also, the directory structure does not have leading zeros on the month/date (i.e., 2-5, NOT 02-05).
Here is the input code that I have so far. It gives me a start date of today (which I need to change), and gives me the correct end date based on the test length. As you can see, I have not been able to get very far in this:
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;
Upvotes: 2
Views: 109
Reputation: 54323
Here is an approach that uses DateTime. You don't need to create a DateTime::Duration object, DateTime does that implicitly for you whenever you use date math.
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;
I left out the user input stuff and just set some values. Basically it builds each day, creates the folder names and puts them into an array.
Output
\2016\4-9
\2016\4-10
\2016\4-11
\2016\4-12
Upvotes: 0
Reputation: 126722
I don't think you have it clear in your mind exactly what you need, but this should help
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
Upvotes: 1