Chon-Ji has asked for the wisdom of the Perl Monks concerning the following question:

What is the difference between timegm and timelocal? This question might not be perl related but can you think of other ways that I can compute for the time elapsed given that I have two timestamps. The format of the time stamp is YYYYMMDDHHMMSS Currently, what I do is to parse the time string and and use timelocal or timegm to get the seconds conversion. The reason why I am asking is that the timelocal function seem to be computationally expensive. I processed millions of transactions and it took around 6 hours to complete. But when I removed the timelocal function the processing time was reduced to 2 hours.

Replies are listed 'Best First'.
Re: Timegm and timelocal
by Zaxo (Archbishop) on Jun 07, 2007 at 06:41 UTC

    That depends entirely on where your time data comes from. If it is based on local time, you have no choice but timelocal. If it is based on UTC, timegm will do.

    After Compline,
    Zaxo

      I see, since I just need the conversion to compute for the seconds elapsed then timegm will do right?

        Right, so long as you can ignore leap seconds.

        After Compline,
        Zaxo

Re: Timegm and timelocal
by Skeeve (Parson) on Jun 07, 2007 at 08:47 UTC

    Did I understand correct, that you are interested in just the difference?

    Then, if your times are really at most 10 minutes apart, I don't think that you need to take care of the date or even the hour. Even if the daylight saving time occured between two timestamps. You just need to check the minutes and seconds. if the result is negative, just add 60 minutes and you should be okay.

    Here a small example:

    my $a="20070101005959"; my $z="20070101010101"; my $t1=substr($a,-4,2)*60+substr($a,-2); my $t2=substr($z,-4,2)*60+substr($z,-2); print (($t2+3600-$t1)%3600);

    s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
    +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
      Yes, I'm interseted to see the difference since my application executes faster when using timegm compared to timelocal. It seems for my application I could juts use timegm since I'm only using it to compute the elapsed number of seconds, and my expected value shouldn't exceed 600 seconds since the timestamps were taken at very little intervals within the day.
      I have question for this part of your code print (($t2+3600-$t1)%3600 Why again do I need to add 3600 to $t2

        You don't need to, but if you do, you don't need to check for negative values afterwards.

        You can replace this by:

        my $r= $t2-$t1; $r+= 3600 if $r<0;

        This code may even be faster because you don't need to divide by 3600.


        s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
        +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
Re: Timegm and timelocal
by andreas1234567 (Vicar) on Jun 07, 2007 at 07:33 UTC
    I assume you mean gmtime and localtime.

    Unless this benchmark is fundamentally flawed, it seems gmtime is 2x faster than localtime. See perlfunc for more.
    #!/usr/bin/perl -sw use strict; use Benchmark; our $ITERATIONS ||= 1e7; timethese($ITERATIONS, { gmtime => sub { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime(time); }, localtime => sub { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) += localtime(time); }, } ); __END__ $ perl 619744.pl Benchmark: timing 10000000 iterations of localtime, gmtime... localtime: 101 wallclock secs (51.07 usr + 45.89 sys = 96.96 CPU) @ 1 +03135.31/s (n=10000000) gmtime: 62 wallclock secs (29.76 usr + 27.94 sys = 57.70 CPU) @ 17 +3310.23/s (n=10000000)
    #!/usr/bin/perl -sw use strict; use Benchmark; use Time::Local; our $ITERATIONS ||= 1e7; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime(time); timethese($ITERATIONS, { timegm => sub { my $time = timegm($sec,$min,$hour,$mday,$mon, +$year); }, timelocal => sub { my $time = timelocal($sec,$min,$hour,$mday,$m +on,$year); }, } ); __END__ $ perl 619744.pl Benchmark: timing 10000000 iterations of timegm, timelocal... timegm: 95 wallclock secs (89.95 usr + 0.06 sys = 90.01 CPU) @ 11 +1098.77/s (n=10000000) timelocal: 811 wallclock secs (654.30 usr + 112.15 sys = 766.45 CPU) +@ 13047.17/s (n=10000000)
    Update: Now comparing Time::Local functions.
    --
    print map{chr}unpack(q{A3}x24,q{074117115116032097110111116104101114032080101114108032104097099107101114})

      I think OP refers to timegm() and timelocal() from Time::Local.

      After Compline,
      Zaxo