perln00b
perln00b

Reputation: 9

perl date fetch script assistance

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

Answers (2)

Sobrique
Sobrique

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

Matt Jacob
Matt Jacob

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

Related Questions