-1

Is there any way to subtract time in below format to give a time difference, without using a perl module?

I am expecting result like:

05:16:54:365  - 05:16:51:209 = 000003.156000

if required, what perl module could be used here?

user381862
  • 189
  • 1
  • 4
  • 8
  • 1
    I'd say your best bet is [DateTime](https://metacpan.org/module/DateTime). – squiguy Aug 02 '13 at 04:00
  • 1
    See closely related question [Convert absolute time into relative time](http://stackoverflow.com/questions/17986013/convert-absolute-time-into-relative-time) also asked by [user381862](http://stackoverflow.com/users/381862/user381862). You were already told that the [DateTime](http://search.cpan.org/perldoc?DateTime) family of modules can do the job. Yes, you can fairly easily write a function to take two strings in the format shown and produce an answer in the format shown — this is where the 'what have you tried' questions arise. – Jonathan Leffler Aug 02 '13 at 04:00

1 Answers1

1

With some fairly major reservations, this code does the job you need for the data given:

#!/usr/bin/env perl
use strict;
use warnings;

use Test::Simple tests => 1;

sub time_check
{
    my($tv, $hh, $mm, $ss, $ms) = @_;
    die "Hours ($hh) out of range 00..23 in $tv" if $hh < 0 || $hh > 23;
    die "Minutes ($mm) out of range 00..59 in $tv" if $mm < 0 || $mm > 59;
    die "Seconds $(ss) out of range 00..59 in $tv" if $ss < 0 || $ss > 59;
    die "Milliseconds ($ms) out of range 000..999 in $tv" if $ms < 0 || $ms > 999;
    return;
}

sub time_seconds
{
    my($tm) = @_;
    my($hh, $mm, $ss, $ms) = split /:/, $tm;
    time_check($tm, $hh, $mm, $ss, $ms);
    my $rv = ($hh * 60 + $mm) * 60 + $ss + ($ms / 1000.0);
    return $rv;
}

sub time_diff
{
    my($s1, $s2) = @_;
    my $t1 = time_seconds($s1);
    my $t2 = time_seconds($s2);
    my $rv = sprintf "%013.6f", $t1 - $t2;
    return $rv;
}

my $v1 = "05:16:54:365";
my $v2 = "05:16:51:209";
my $ev = "000003.156000";

ok(time_diff($v1, $v2) eq $ev, "time diff $v1 - $v2 = $ev");

One of the bigger problems is that if you don't specify all three digits for the milliseconds value, you will misinterpret the time. That is, 05:16:54:36 would be treated as 05:16:54:036 and 05:16:54:3 would be treated as 05:16:54:003. It also isn't clear from the pair of time values given whether you can ever get negative results (reverse the order of the two values?) and if so, what the required format is. I've assumed that the values are constrained to represent times on the 24 hour clock, but I've rejected 24:00:00:000 as midnight at the end of the day (which might be useful). Etc. These are details that a real calendar module will deal with. The error handling is abominable; die is not the long-term acceptable solution.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278