AskQuestionsP
AskQuestionsP

Reputation: 319

How to calculate time difference in perl using POSIX module?

I am new to perl scripting. I have a need where in I require to find the difference of two dates in the Days/Hrs/minutes/seconds, provided I just have POSIX module ( I can't use Time::Piece or DateTime or... module)

Like,

$date1 = Tue Nov 30 10:53:38 2021;
$date2 = Fri Dec 10 02:12:25 2021;

$output = $date2 - $date1 :: here $output should be 09 days, 3hrs, 19 mins, 47 secs.

Can you please tell me how do we achieve this: Parsing, calculation?

Your help will be highly appreciated.

Thanks!

Upvotes: 0

Views: 288

Answers (1)

Polar Bear
Polar Bear

Reputation: 6798

Algorithm to a solution of the problem can be achieved with POSIX::mktime function.

Input dates require some 'massaging' to bring provided dates to expected representation by mktime function what is achieved by date2epoch function which returns representation of the date in seconds.

Once dates was converted to seconds it is a matter of trivial computation to obtain time difference represented in days/hours/minutes/seconds.

Note #1: It is assumed that dates obtained in same timezone.

Note #2: OP's date difference computation is incorrect

use strict;
use warnings;
use feature 'say';

use POSIX;

my $date1 = 'Tue Nov 30 10:53:38 2021';
my $date2 = 'Fri Dec 10 02:12:25 2021';

my $diff = date_diff($date1,$date2);

printf "Date difference: %02d days %02d hours %02d min %02d sec\n",
       $diff->@{qw/days hours min sec/};

sub date_diff {
    my $date1 = shift;
    my $date2 = shift;

    my $diff;
    my $sec_diff = date2epoch($date2) - date2epoch($date1);

    $diff->{sec}   = $sec_diff % 60;
    $diff->{min}   = ($sec_diff % 3600 - $diff->{sec} ) / 60;
    $diff->{hours} = $sec_diff / 3600 % 24;
    $diff->{days}  = int( $sec_diff / ( 24 * 3600 ) );

    return $diff;
}

sub date2epoch {
    my $str_date = shift;

    my($months,$date,$epoch);
    
    $months->@{qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/} = (0..11);

    $date->@{qw/week_day month month_day time year/} = split(' ', $str_date);
    $date->@{qw/hour min sec/} = split(':', $date->{time});
    
    $date->{month} = $months->{ $date->{month} };
    $date->{year} -= 1900;
    
    $epoch = POSIX::mktime( $date->@{qw/sec min hour month_day month year/} );
    
    return $epoch;
}

Output

Date difference: 09 days 15 hours 18 min 47 sec

Upvotes: 3

Related Questions