Reputation: 9
I was just having a go at perl. I was trying to extract the date and time from a line in a text file that begins with
Date: 05/Feb/2017 21:30:00 PST - 06/Feb/2017 06:00:00 PST
I have managed to scavenge a script but Im trying to modify it so it extracts the above to
start date - 2017-02-05 21:30:00
end date - 2017-02-06 06:00:00
any help would be appreciated
#Is it a reg date
} elsif (!$start && $line[$i] =~ /^Date: (.+?) - (.+)$/i) {
$regstartdate = $1;
$regenddate = $2;
} elsif (!$start && $line[$i] =~ /^Date: (.+)$/i) {
#Monday 3rd July 2006
#Friday 30th June 2006 01:00 Hrs EST
$regstartdate = $1;
eval{
$start = &dateconv($regstartdate);
$end = $start;
1;
}
or do{
warn "Could not process start date: $regstartdate";
};
} elsif (!$start && $line[$i] =~ /^Time:\s*(\d+:\d+)[\s\-]+\s+(\d+:\d+)\s+[hH][rR][sS]\s+(\w+)$/i) {
$tz = $3;
$twestartdate = $regstartdate . " ".$1." Hrs ".$3;
$tweenddate = $regenddate . " ".$2." Hrs ".$3;
$start = &dateconv($regstartdate);
$end = &dateconv($regenddate);
} elsif (!$start && $line[$i] =~ /^Time:\s*(\d+:\d+)[\s*\-]+\s*(\d+:\d+)\s+(\w+)$/i) {
$tz = $3;
$regstartdate = $regstartdate . " ".$1." Hrs ".$3;
$regenddate = $regenddate . " ".$2." Hrs ".$3;
$start = &dateconv($regstartdate);
$end = &dateconv($regenddate);
#Is it a reg Time
} elsif (!$start && $line[$i] =~ /^Interruption Time: (\d+:\d+)[\s\-]+(\d+:\d+) (\w+)/i) {
$regstartdate = $regstartdate . " " . $1 . " Hrs " . $3;
$regenddate = $regenddate . " " . $2 . " Hrs " . $3;
$start = &dateconv($regstartdate);
$end = &dateconv($regenddate);
#Is is the start time ?
} elsif (!$start && $line[$i] =~ /^Duration:\s*START DATE (.*)/i) {
$start = &dateconv($1);
#Is it the end time ?
} elsif (!$end && $line[$i] =~ /^END DATE (.*)/i) {
my $endtime = $1;
$end = &dateconv($endtime);
$endtime =~ m/(\w{1,2}ST)/g;
$tz = $1;
Upvotes: 0
Views: 53
Reputation: 53478
Offering a solution using Time::Piece
which I prefer - both because I like the interface, but also because it's core as of perl 5.9.5
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $input_format = '%d/%b/%Y %H:%M:%S';
my $output_format = '%Y-%m-%d %H:%M:%S';
while (<DATA>) {
if ( my ( $start_str, $end_str ) = m/Date: (.*) PST - (.*) PST/ ) {
my $start = Time::Piece->strptime( $start_str, $input_format );
my $end = Time::Piece->strptime( $end_str, $input_format );
print "Start:\t", $start->strftime($output_format), "\n";
print "End: \t", $end ->strftime($output_format), "\n";
}
}
__DATA__
Date: 05/Feb/2017 21:30:00 PST - 06/Feb/2017 06:00:00 PST
The reason I like it is because the $start
and $end
in the above, are 'time objects' so you can do things like:
print $start -> epoch;
print "Elapsed time: ", $end - $start, "s\n";
Upvotes: 2
Reputation: 6553
If you use the DateTime module, parsing and formatting those date strings is trivial:
use strict;
use warnings;
use 5.010;
use DateTime;
use DateTime::Format::Strptime;
my $fmt = DateTime::Format::Strptime->new(pattern => '%d/%b/%Y %H:%M:%S');
my $line = 'Date: 05/Feb/2017 21:30:00 PST - 06/Feb/2017 06:00:00 PST';
$line =~ s/^Date: //;
my @dates = split(/\s*-\s*/, $line);
for my $date (@dates) {
my $dt = $fmt->parse_datetime($date);
say $dt->ymd . ' ' . $dt->hms;
}
Produces:
2017-02-05 21:30:00
2017-02-06 06:00:00
You can adjust the formatting as you see fit.
Upvotes: 0