Time difference in seconds

38,524

Solution 1

In perl, there is always more than one way to do something. Here's one which uses only a module that comes standard with Perl:

#! perl -w

use strict;
use Time::Local;

my $d1 = "Feb 3 12:03:20";
my $d2 = "Feb 4 00:00:30";

# Your date formats don't include the year, so
# figure out some kind of default.
use constant Year => 2012;


# Convert your date strings to Unix/perl style time in seconds
# The main problems you have here are:
# * parsing the date formats
# * converting the month string to a number from 1 to 11
sub convert
{
    my $dstring = shift;

    my %m = ( 'Jan' => 0, 'Feb' => 1, 'Mar' => 2, 'Apr' => 3,
            'May' => 4, 'Jun' => 5, 'Jul' => 6, 'Aug' => 7,
            'Sep' => 8, 'Oct' => 9, 'Nov' => 10, 'Dec' => 11 );

    if ($dstring =~ /(\S+)\s+(\d+)\s+(\d{2}):(\d{2}):(\d{2})/)
    {
        my ($month, $day, $h, $m, $s) = ($1, $2, $3, $4, $5);
        my $mnumber = $m{$month}; # production code should handle errors here

        timelocal( $s, $m, $h, $day, $mnumber, Year - 1900 );
    }
    else
    {
        die "Format not recognized: ", $dstring, "\n";
    }
}

my $t1 = convert($d1);
my $t2 = convert($d2);

print "Diff (seconds) = ", $t2 - $t1, "\n";

To make this really production-ready, it needs better handling of the year (for example, what happens when the start date is in December and end date in January?) and better error handling (for example, what happens if the 3-char month abbreviation is mispelled?).

Solution 2

#!/usr/bin/perl

my $Start = time();
sleep 3;
my $End = time();
my $Diff = $End - $Start;

print "Start ".$Start."\n";
print "End ".$End."\n";
print "Diff ".$Diff."\n";

This is a simple way to find the time difference in seconds.

Solution 3

There seems to be a convenient Date::Parse. Here's the example:

use Date::Parse;

print str2time ('Feb 3 12:03:20') . "\n";

And here's what it outputs:

$ perl test.pl
1328288600

which is: Fri Feb 3 12:03:20 EST 2012

I'm not sure how decent the parsing is, but it parses your example just fine :)

Solution 4

In the spirit of TMTOWTDI, you can leverage the core Time::Piece :

#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $when = "@ARGV" or die "'Mon Day HH:MM:SS' expected\n";
my $year = (localtime)[5] + 1900;
my $t = Time::Piece->strptime( $year . q( ) . $when, "%Y %b %d %H:%M:%S" );
print "delta seconds = ", time() - $t->strftime("%s"),"\n";

$ ./mydelta Feb 3 12:03:20

delta seconds = 14553

The current year is assumed and taken from your localtime.

Solution 5

Assuming you want to use Date::Calc, convert the two values to "time" values with Date_to_Time and subtract the values to get the difference in seconds. But to do this, you need to convert from the strings to YY MM DD hh mm ss values to pass to Date_to_Time first.

Share:
38,524
Xi Vix
Author by

Xi Vix

Updated on June 08, 2021

Comments

  • Xi Vix
    Xi Vix about 3 years

    In a Perl program I have a variable containing date / time in this format:

    Feb 3 12:03:20  
    

    I need to determine if that date is more than x seconds old (based on current time), even if this occurs over midnight (e.g. Feb 3 23:59:00 with current time = Feb 4 00:00:30).

    The perl date / time information I've found is mind-boggling. Near as I can tell I need to use Date::Calc, but I am not finding a seconds-delta. Thanks :)

  • Xi Vix
    Xi Vix over 12 years
    how would I get the current date into that same format for comparison? localtime(time) gives a much longer number.
  • Ilmari Karonen
    Ilmari Karonen over 12 years
    @xivix: You don't need localtime, just use time: it returns a Unix timestamp (seconds since 1 Jan 1970 00:00:00 UTC), just like str2time.
  • pilcrow
    pilcrow over 12 years
    @xivix, it's unnecessarily complicated for what you want. vmpstr's answer is totally workable here.
  • theglauber
    theglauber over 12 years
    It all depends on how many modules you can or will use. See the answer by @vmpstr, using Date::Parse. If installing that module is acceptable, go for it. It's likely doing a better work of handling different data formats and possible errors than this short snippet of code.
  • theglauber
    theglauber over 12 years
    Fortunately for your needs, perl uses the Unix convention of measuring time in seconds since 1 Jan 1970, so the output of str2parse above is already in seconds, and you can do the math.
  • thinkhy
    thinkhy almost 10 years
    I like this code snippet, simple and workable without additional dependency .
  • Zaid
    Zaid over 8 years
    Not sure why, but $t->epoch works while $t->strftime("%s") doesn't
  • JRFerguson
    JRFerguson over 8 years
    @Zaid What version of Time::Piece are you using? It looks like 1.20 added strftime support for %s.
  • RichVel
    RichVel over 8 years
    vmpstr's answer is just 2 lines, and uses a robust CPAN module, which to me is a much better approach.
  • RichVel
    RichVel over 8 years
    This doesn't answer the question at all, which is about comparing times in two variables.
  • lepe
    lepe over 7 years
    $t->epoch seems to use some localization setting which I'm not aware of. In my case, epoch is returning EDT time zone value, while I'm actually in JST (Japan time) time. However, strftime("%s") returns the correct value in seconds (JST), which is consistent with time().
  • Keve
    Keve over 6 years
    True, BUT it allows ... a.) the person who asked the original question to consider a different approach, which may be simpler than his/her original way; b.) other people finding this page through a web search to easily measure the seconds passed. I belong to the latter, and I very much like Sjoerd's example. Simple, and has no dependencies. Just what I was looking for.
  • Yordan Georgiev
    Yordan Georgiev over 5 years
    and of course solves my problem after 3 seconds googling , so thank you ! BTW ... one guru told me that the proper var names should be : start_time , stop_time and begin_time -> end_time ...