I came across an interesting question on StackOverflow. Unfortunately the question was closed before I could answer. I'd like to answer it.
Can I convert
uniqid()to a timestamp?
From the PHP documentation on
without being passed any additional parameters the return value is little different from
The comments note that
uniqid() outputs a hexadecimal string. So let’s convert
microtime() to a hexadecimal string and compare it to
<?php $microtime = microtime(true); $id = uniqid(); echo dechex($microtime); // 5228cee5 echo $id; // 5228cee5564a0
We see both share the same prefix (
5228cee5). So what are the remaining characters of
Turns out the answer is pretty obvious. It's the microseconds. But
uniqid() does not simply multiply
$microtome by 1,000,000. Instead it appends the microseconds as a hexidecimal string.
Let’s take another look:
<?php $microtime = microtime(); $id = uniqid(); list($microseconds, $timestamp) = explode(' ', $microtime); $suffix = str_replace(dechex($timestamp), '', $id); echo $microseconds; // 0.23929900 echo '0.', hexdec($suffix); // 0.239327
Pretty close. The few nanosecond difference is the runtime between executing line 1 and 2.
microtime() we've proven
uniqid(), without parameters, is the concatenation of a timestamp and microseconds as hexadecimal strings.
Why then did I say sort of?
The suffix. If you run the last script enough you'll notice an inconsistency for low microsecond values.
Notice the leading zeroes are missing. So you can’t get a timestamp with microsecond precision from
However, given this inconsistency, can we trust the suffix is a specific number of hexadecimal characters (i.e. 5)?
The documentation states, without parameters,
uniqid() returns 13 characters. That said, the simplest code to get the timestamp from
uniqid() is to extract the prefix:
<?php $timestamp = substr(uniqid(), 0, -5); echo date('r', hexdec($timestamp)); // Thu, 05 Sep 2013 15:55:04 -0400
Why the negative anchor? Consider the Unix timestamp
4294967296. You don't want to start Y2.1K!
After this exercise I reviewed the source code for
uniqid() to confirm using a negative anchor (
-5) is indeed safe.
So yes, you can convert
uniqid() to a timestamp (without microsecond precision).
Find this interesting? Let's continue the conversation on Twitter.