How to convert microtime() to HH:MM:SS:UU
Asked Answered
W

3

23

I was measuring some curl requests and I used microtime(true). The example output would be 3.1745569706

This is 3.1745569706 seconds. I want to convert that to a somewhat more readable format, let's say 00:00:03:17455 (HOURS:MINUTES:SECONDS:MILLISECONDS)

$maxWaitTime = '3.1745569706';
echo gmdate("H:i:s.u", $maxWaitTime);

// which returns
00:00:01.000000

echo date("H:i:s.u" , $maxWaitTime)
// which returns
18:00:01.000000

That looks wrong. I'm not quite sure what I'm missing here.

How do I convert microtime() to HH:MM:SS:UU ?

Wardmote answered 29/5, 2013 at 22:53 Comment(2)
<?php echo gmdate("H:i:s.u", 3.1745569706); ?> returns: 00:00:03.000000Haakon
gmdate() expects an integer timestamp value, and will cast a float to an int (effectively rounding down) - use DateTime (php.net/manual/en/datetime.format.php) if you want fractional secondsJabon
O
29

From the PHP.net article on date() which is similar to gmdate(), except that the time is returned in GMT:

Since this function only accepts integer timestamps the u format character is only useful when using the date_format() function with user based timestamps created with date_create().

Use something like this instead:

list($usec, $sec) = explode(' ', microtime()); //split the microtime on space
                                               //with two tokens $usec and $sec

$usec = str_replace("0.", ".", $usec);     //remove the leading '0.' from usec

print date('H:i:s', $sec) . $usec;       //appends the decimal portion of seconds

Which prints: 00:00:03.1745569706

If you want you can use round() to round the $usec var even more.

If you use microtime(true) use this instead:

list($sec, $usec) = explode('.', microtime(true)); //split the microtime on .
Outstay answered 29/5, 2013 at 23:13 Comment(4)
What if you replace the predefined variable with microtime() (check my updated reply)Outstay
I get 18:24:570.94270700, I'm soo confused, but I believe it's getting server time or something...Wardmote
I'm not sure, but I suspect something is wrong on your server.Outstay
If you have to use microtime(true), then the output format is a float number (obviously with a dot delimiter). You should therefore use list($sec, $usec) = explode('.', $maxWaitTime); instead.Translucent
A
6
<?php

function format_period($seconds_input)
{
  $hours = (int)($minutes = (int)($seconds = (int)($milliseconds = (int)($seconds_input * 1000)) / 1000) / 60) / 60;
  return $hours.':'.($minutes%60).':'.($seconds%60).(($milliseconds===0)?'':'.'.rtrim($milliseconds%1000, '0'));
}

echo format_period(3.1745569706);

OUTPUT

0:0:3.174
Arcanum answered 29/5, 2013 at 23:51 Comment(6)
Thanks for the function helped me a lot - it needs to add (ini) before $hours i.e. 'return (ini)$hours' etc. - was pulling my hair thinking that my code was wrong - until looked over your functionPeriodontal
@Periodontal you should have added (ini) before $hours? What exactly is this (ini) type converting to? And either with or without (int) at the return part it shouts the same result.Sphygmo
@Sphygmo - the (ini) prevents hours to be shown with decimals. Try the function with microtime 121.87023377419 and you'll see what i mean.Periodontal
@Periodontal , to me (ini) shouts an error, maybe I am just missing the right php version, maybe it is (int), but in that case won't have the behaviour you described.Sphygmo
@khael, did you try the function with the above number? -It breaks the readable 00:00:00.000 format - Im using php 5.5.Periodontal
@Periodontal this is getting tiring, yes, I tried it, and as far as I know the syntax (something) is a type conversion, therefore (ini) should, by my knowledge, try to convert whatever is after it to the type ini. And anyway, with the description provided the function seems to work just fine, needed only some minor adjustments.Sphygmo
T
0

Assuming one really cares about microseconds, which is admittedly rare, then one should not use any representation that involves floats.

Instead use gettimeofday() which will return an associative array that contains the seconds and microseconds as integers.

$g1 = gettimeofday();
# execute your process here
$g2 = gettimeofday();

$borrow  = $g2['usec'] < $g1['usec'] ;
$seconds = $g2['sec'] - $g1['sec'] - $borrow ;
$micros  = $borrow*1000000 + $g2['usec'] - $g1['usec'] ;
$delta   = gmdate( 'H:i:s.', $seconds ).sprintf( '%06d', $micros );
Talkington answered 2/6, 2018 at 2:35 Comment(2)
too bad the overhead of calling gettimeofday() effectively wipes out any theoretical gain in accuracy :-(Talkington
Apparently gettimeofday() is also potentially subject to wild swings if the clock gets updated by ntp (or otherwise changes).Talkington

© 2022 - 2024 — McMap. All rights reserved.