Search code examples
perldatetime

Time interval between two dates with Perl


I'm adding two dates and trying to calculate the time, but I'm getting the following error:

Error parsing time at /usr/local/lib/x86_64-linux-gnu/perl/5.30.0/Time/Piece.pm line 598.

I install Time::Piece with cpan: cpan Time::Piece.

This my code:

our @months = qw( 01 02 03 04 05 06 07 08 09 10 11 12 );
our @days = qw(Domingo Segunda Treça Quarta Quinta Sexta Sabado Domingo);

 ($sec,$min,$hour,$mday,$mon,$year,$wday,$day,$isdst) = localtime();
 our $ano = "2021";
 our $day = "$mday";
 our $mes = $months[$mon];
 our $data = $mes."-".$day."-".$ano; 
 our $horario = $hour.":".$min.":".$sec;
 our $horario2 = $hour.":".$min.":".$sec;
 our $data1 = $ano."-".$mes."-".$day;
 our $data2 = $day."/".$mes."/".$ano;
 our $str1 = 'Execution completed at '.$data2.' '.$horario.' AM';

 our @mes = qw( Jan Feb Mar APr May Jun Jul Agu Sep Oct Nov Dec );
 our @days = qw(Domingo Segunda Treça Quarta Quinta Sexta Sabado Domingo);

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();

$nomeMes = $mes[$mon];

our @mes = qw( Jan Feb Mar APr May Jun Jul Agu Sep Oct Nov Dec );
our @days = qw(Domingo Segunda Treça Quarta Quinta Sexta Sabado Domingo);

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();

our $data2 = $day."/".$mes."/".$ano; 
our $horario = $hour.":".$min.":".$sec;

my $str2 = 'Execution completed at '.$data2.' '.$horario.' AM';
my @times = map Time::Piece->strptime(/(\d.+M)/, '%m/%d/%Y %H:%M:%S %p'), $str1, $str2;

my $delta = $times[1] - $times[0];

$tempo = $delta->pretty;

What am I doing wrong? What can I do to make this function work?


Solution

  • The matched pattern of $str1 is 20/12/2021 13:58:3 AM

    Problems:

    • There's no 20th month

    • There's no 13 AM

    • Can give the wrong answer near a switch from Daylight-Saving Time.

    Also, there's a couple of problems strptime ignores:

    • You should be using %I instead of %H for 12-hour time.

    • There's a lack of leading zeros where they are normally expected (minutes and seconds).


    You appear to be asking the following:

    Given the year, month, day, hour, minute and second components of a local time, how do I obtain the corresponding epoch time so I can perform a difference?

    To achieve this, use Time::Local's timelocal*.

    use Time::Local qw( timelocal_posix );
    
    my $time = timelocal_posix( $sec, $min, $hour, $day, $month - 1, $year - 1900 );
    

    You could also use DateTime. This more powerful module can give you differences in amounts other than seconds.

    Either way, you will still have problems near a switch from DST. There's simply not enough information to address that. That's the problem with dealing with local times with no offset.