Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

converting Time::HiRes

by Lhamo Latso (Scribe)
on Sep 13, 2004 at 20:16 UTC ( #390711=perlquestion: print w/replies, xml ) Need Help??

Lhamo Latso has asked for the wisdom of the Perl Monks concerning the following question:

Hello Time Travelers,

I am having trouble converting gettimeofday values back to a formatted date. I am using the Time::HiRes module as a test for some hi-res Oracle tim values. The tim values are in microseconds. To no surprise, my results using Time::HiRec are similarly way off, just like the Oracle tim values.

use Time::HiRes qw(gettimeofday); my $t0 = [gettimeofday]; print "t0: ". localtime($t0) ."\n"; print "trc msec: ". localtime(1068916117987100) ."\n"; print "trc sec: ". localtime(1068916117) ."\n";

My results:

t0: Mon Apr 15 04:20:16 1974
trc msec: Wed Dec 31 17:59:59 1969
trc sec: Sat Nov 15 11:08:37 2003

The date of the "trc msec:" is 2004-09-07 10:15:04, not Nov-2003.

Thanks for any help and direction. This is Perl v5.6.1 on RedHat Linux.

Replies are listed 'Best First'.
Re: converting Time::HiRes
by BrowserUk (Pope) on Sep 13, 2004 at 20:48 UTC

    You need to re-read the docs. This line of code:

    my $t0 = [gettimeofday];

    Is putting two values (seconds and microseconds) into an anonymous array and assigning a reference to that array to $t0. You then pass that reference to localtime() and get strange results.

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: converting Time::HiRes
by tachyon (Chancellor) on Sep 13, 2004 at 21:51 UTC
    use Time::HiRes qw(gettimeofday); my $sec = gettimeofday(); # scalar context my ( $s, $ms ) = gettimeofday(); # list context my $float_t = "$s.$ms"; printf "Seconds since epoch (scalar): %d\n", $sec; printf "Seconds since epoch (list): %d.%d\n", $s, $ms; printf "Seconds since epoch (float): %.6f\n", $float_t; printf "Scalar: %s\nList: %s\nFloat: %s\n", scalar(localtime($sec)), scalar(localtime("$s.$ms")), scalar(localtime($float_t)); __DATA__ Seconds since epoch (scalar): 1095126990 Seconds since epoch (list): 1095126990.878512 Seconds since epoch (float): 1095126990.878512 Scalar: Tue Sep 14 11:56:30 2004 List: Tue Sep 14 11:56:30 2004 Float: Tue Sep 14 11:56:30 2004



      Thanks, the scalar of localtime works, with a decimal correctly placed:
      print scalar(localtime(1068837428.812901))."\n";

      My real problem is with the Oracle trace data. It has a time value in microseconds since the epoch, but the conversion appears to be off by 9 months. The print statement above is from September 2004, but the conversion lands in November 2003. As in the following source data:

      *** SESSION ID:(92.34308) 2004-09-06 11:52:07.103 APPNAME mod='sqlplus@prod90db (TNS V1-V3)' mh=0 act='' ah=0 ===================== PARSING IN CURSOR #1 len=69 dep=0 uid=0 oct=42 lid=0 tim=1068837428812 +901 hv=...

      It's time to read the Oracle docs again!!

        Actually, scratch the V$Timer bit. There appears to be a plausible conversion factor.

        my $time = convert_tim(1068837428812901); print "Epoch $time\n", scalar gmtime $time, "\n"; # Seem to need a conversion factor of 976,562.5 is 1,000,000,000/1024 sub convert_tim { my $factor = 1_000_000_000/1024; return $_[0]/$factor; } __DATA__ Epoch 1094489527.10441 Mon Sep 6 16:52:07 2004

        Now the plaintext date in your log was 2004-09-06 11:52:07.103 so we get the date right, and the minute and second (down to 5 sig figs). This would appear to be a little to improbable for it to be a coincidence. I expect your DB GMT offset is -5 which is why the hours are out.



        The problem is that tim records the value in v$timer. Here is the man page that this was taken from:


        This view lists the elapsed time in hundredths of seconds. Time is measured since the beginning of the epoch, which is operating system specific, and wraps around to 0 again whenever the value overflows four bytes (roughly 497 days).



      This is the wrong way to handle $ms !!

      It will fail unless there are 6 significant digits!

      $err = ( $ms < 100000 ? 'wrong' : '' ); printf "Seconds since epoch (float): %.6f\n", $sec; # $sec is a float, print it like that... printf "Seconds since epoch (list): %d.%d $err\n", $s, $ms; printf "Seconds since epoch (float): %.6f $err\n", $float_t;
      Seconds since epocg (float): 1349360875.006262 Seconds since epoch (list): 1349360875.6267 wrong Seconds since epoch (float): 1349360875.626700 wrong

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://390711]
Approved by graff
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2020-01-28 20:05 GMT
Find Nodes?
    Voting Booth?