Jason McCreary

a PHP and iOS developer. a thinker.

Convert uniqid() to a timestamp

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?

Sort of.

From the PHP documentation on uniqid():

without being passed any additional parameters the return value is little different from microtime()

The comments noted that uniqid() outputs a hexadecimal string. The following script compares uniqid() to the output of microtime() converted to a hexadecimal string.

1
2
3
4
5
6
7
<?php
$microtime = microtime(true);
$id = uniqid();

echo dechex($microtime);
echo PHP_EOL;
echo $id;
Script Output
1
2
5228cee5
5228cee5564a0

Immediately we see both have the same prefix. So what are the remaining characters of uniqid()?

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.

Another quick script as proof:

1
2
3
4
5
6
7
8
9
<?php
$microtime = microtime();
$id = uniqid();

list($microseconds, $timestamp) = explode(' ', $microtime);
$suffix = str_replace(dechex($timestamp), '', $id);

echo $microseconds, PHP_EOL;
echo '0.', hexdec($suffix), PHP_EOL;
Script Output
1
2
0.23929900
0.239327

Pretty close. The few nanosecond difference is literally the runtime between executing line 1 and 2.

So using 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.

Script Output
1
2
0.00997400
0.9984

Notice the missing zeroes. 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:

1
2
3
<?php
$timestamp = substr(uniqid(), 0, -5);
echo date('r', hexdec($timestamp));
Script Output
1
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 this code is indeed safe.

So yes, you can convert uniqid() to a timestamp.

Comments