1

I've got two "similar" questions about microtime accuracy.


1) As was suggested in PHP online documentation, to get time in microseconds, I'm using a following code with microtime() function (looped):

<?php
    for ($i = 0; $i < 10; $i++) {
        list($usec, $sec) = explode(' ', microtime()); //split the microtime on space
        $usec = str_replace('0.', ' ', $usec); // remove the leading '0.' from usec
        echo date('YmdHis', $sec) .' '. $usec ."<br>"; 
    }
?>

I'm getting following results:

20140526135144 72254300
20140526135144 72255900
20140526135144 72256500
20140526135144 72257100
20140526135144 72257600
20140526135144 72258100
20140526135144 72258600
20140526135144 72259100
20140526135144 72259600
20140526135144 72260100

Micro means 1/100000 as far as I'm concerned. So why does microtime return 8 integers for "micro" part, and the last two are always zeros? Or I should play some lottery because I'm so happy :)?


2) Microtime is sometimes used to generate uniqid for example. But when I run:

for ($i = 0; $i < 10; $i++) {
    echo microtime()."<br>";
}

I'm getting:

0.21820300 1401105400
0.21821000 1401105400
0.21821100 1401105400
0.21821200 1401105400
0.21821300 1401105400
0.21821300 1401105400 // - the same as precursor
0.21821400 1401105400
0.21821500 1401105400
0.21821500 1401105400 // - the same as precursor
0.21821600 1401105400

How is that possible? My computer is not that fast as newer one. Is this dangerous? BTW I'm using additional "br" output, which makes the code run slower :P.


UPDATE According to comments, this is microdate(true).

1401106486.9772
1401106486.9772
1401106486.9772
1401106486.9772
1401106486.9772
1401106486.9772
1401106486.9772
1401106486.9772
1401106486.9772
1401106486.9772

To cite Zorba the Greek: Total catastrophy!

Jacek Kowalewski
  • 2,551
  • 2
  • 19
  • 33

2 Answers2

3

There are two issues here: The fact that the script is executed very fast and that "echo" outputs only the first few decimal points. This script gives more plausible results:

for ($i = 0; $i < 10; $i++) {
    echo number_format(microtime(true), 10, '.', '') . "\n";
    usleep(1000);
}

It outputs:

1401108499.0024349689
1401108499.0038080215
1401108499.0050148964
1401108499.0061480999
1401108499.0073280334
1401108499.0085520744
1401108499.0096609592
1401108499.0108559132
1401108499.0119121075
1401108499.0130879879
Ondřej Mirtes
  • 4,279
  • 21
  • 36
  • WOW! Echo outputs only few decimal points. I was living in a blissful ignorance. +1 from me, as it dispels my doubts. I will wait with accept, for more votes. Thx a lot! – Jacek Kowalewski May 26 '14 at 12:53
1

I think you should refer to the answer to this question DECIMAL length for microtime(true)? .

Basically microtime makes a system call and is therefore system dependant with a precision limited by the hardware.

As for the security issue, you should not use microtime as a unique id. Have a look at http://www.php.net/manual/en/function.uniqid.php and try to use it with the more_entropy flag.

Community
  • 1
  • 1
ForguesR
  • 3,323
  • 1
  • 14
  • 32