The below script calculates the time difference in decimal number, but I get a rounding error, so I guess it is because of my very bad conversion at the end.
Question
Something tells me, that the expression can be simplified, but what are the math rules in this particular situation, when I have int, modulus and division?
#!/usr/bin/perl
print f("9:00", "16:45");
sub f {
my $t1 = shift @_;
my $t2 = shift @_;
my $m1 = $1*60+$2 if $t1 =~ m/(\d\d?):(\d\d?)/;
my $m2 = $1*60+$2 if $t2 =~ m/(\d\d?):(\d\d?)/;
my $h = int(($m2-$m1)/60);
return $h + ($h*60+$m2-$m1)%60/60;
}
You have already correctly calculated $m1 and $m2 as minutes elapsed since midnight. So why not return the time difference in fractional hours as simply:
return ($m2 - $m1) / 60.0;
As far as the "math rules," maybe it will help to look at your return versus mine and see why they are equivalent (ignoring rounding):
$h + ($h * 60 + $m2 - $m1) % 60 / 60
Notice that ($h * 60) % 60 is zero, so this term essentially drops out, leaving:
$h + ($m2 - $m1) % 60 / 60
Now think about how $h was calculated: it is the quotient of ($m2 - $m1) divided by 60, dropping the remainder (because of int()). On the other hand, ($m2 - $m1) % 60 is exactly the remainder of this division. So the expression above is essentially just adding the remainder fraction, which you dropped from $h, back in. Therefore it has the same result as
($m2 - $m1) / 60
You can use Time::Piece to do simple date/time calculations:
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
my $pattern = '%H:%M';
my $start = Time::Piece->strptime('09:00', $pattern);
my $end = Time::Piece->strptime('16:45', $pattern);
my $diff = $end - $start;
print $diff->hours;
7.75
Note that $diff is actually a Time::Seconds object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With