[php] Getting date format m-d-Y H:i:s.u from milliseconds

I am trying to get a formatted date, including the microseconds from a UNIX timestamp specified in milliseconds.

The only problem is I keep getting 000000, e.g.

$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;

07-28-2013 11:26:14.000000

This question is related to php date timestamp milliseconds

The answer is


If you want to format a date like JavaScript's (new Date()).toISOString() for some reason, this is how you can do it in PHP:

$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));

Sample output:

2016-04-27T18:25:56.696Z

Just to prove that subtracting off the whole number doesn't reduce the accuracy of the decimal portion:

>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"

PHP did round the decimal places, but it rounded them the same way in both cases.


The documentation says the following:

Microseconds (added in PHP 5.2.2). Note that date() will always generate 000000 since it takes an integer parameter, whereas DateTime::format() does support microseconds.

I.e., use DateTime instead.


echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);

example output:

02-06-2019 16:45:03.53811192512512

If you have a need to limit the number of decimal places then the below line (credit mgutt) would be a good alternative. (With the code below, the 6 limits the number of decimal places to 6.)

echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));

example output:

02-11-2019 15:33:03.624493

You can readily do this this with the input format U.u.

$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");

This produces the following output:

04-13-2015 05:56:22.082300

From the PHP manual page for date formats:

  • U = Seconds since the Unix Epoch
  • u = Microseconds

http://php.net/manual/en/function.date.php


Thanks goes to giggsey for pointing out a flaw in my original answer, adding number_format() to the line should fix the case of the exact second. Too bad it doesn't feel quite as elegant any more...

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));

http://php.net/manual/en/function.number-format.php


A note on time zones in response to DaVe.

Normally the createFromFormat() method will use the local time zone if one is not specified.

http://php.net/manual/en/datetime.createfromformat.php

However, the technique described here is initialising the DateTime object using microtime() which returns the number of seconds elapsed since the Unix Epoch (01 Jan 1970 00:00:00 GMT).

http://php.net/manual/en/function.microtime.php

This means that the DateTime object is implicitly initialised to UTC, which is fine for server internal tasks that just want to track elapsed time.

If you need to display the time for a particular time zone then you need to set it accordingly. However, this should be done as a separate step after the initialisation (not using the third parameter of createFromFormat()) because of the reasons discussed above.

The setTimeZone() method can be used to accomplish this requirement.

http://php.net/manual/en/datetime.settimezone.php

As an example:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
echo $now->format("m-d-Y H:i:s.u") . '<br>';

$local = $now->setTimeZone(new DateTimeZone('Australia/Canberra'));
echo $local->format("m-d-Y H:i:s.u") . '<br>';

Produces the following output:

10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818

Note that if you want to input into mysql, the time format needs to be:

format("Y-m-d H:i:s.u")

I benched a few different ways:

1) microtime + sscanf + date:

sscanf(microtime(), '0.%6s00 %s', $usec, $sec);
$date = date('Y-m-d H:i:s.', $sec) . $usec;

I'm not sure why microtime() returns 10 chars (0.dddddd00) for the microseconds part but maybe someone can tell me ?

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { sscanf(microtime(), '0.%6s00 %s', $usec, $sec); $date = date('Y-m-d H:i:s.', $sec) . $usec; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "22372.335910797 ms" // macOS PHP 5.6.30
string(18) "16772.964000702 ms" // Linux PHP 5.4.16
string(18) "10382.229089737 ms" // Linux PHP 7.3.11 (same linux box as above)

2) DateTime::createFromFormat + Datetime->format:

$now = new DateTime('NOW');
$date = $now->format('Y-m-d H:i:s.u');

not working in PHP 5.x ...

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = new DateTime('NOW'); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "45801.825046539 ms" // macOS PHP 5.6.30 (ms not working)
string(18) "21180.155038834 ms" // Linux PHP 5.4.16 (ms not working)
string(18) "11879.796028137 ms" // Linux PHP 7.3.11 (same linux box as above)

3) gettimeofday + date:

$time = gettimeofday();
$date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec'];

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $time = gettimeofday(); $date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec']; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "23706.788063049 ms" // macOS PHP 5.6.30
string(18) "14984.534025192 ms" // Linux PHP 5.4.16
string(18) "7799.1390228271 ms" // Linux PHP 7.3.11 (same linux box as above)

4) microtime + number_format + DateTime::createFromFormat + DateTime->format:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', '')); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "83326.496124268 ms" // macOS PHP 5.6.30
string(18) "61982.603788376 ms" // Linux PHP 5.4.16
string(16) "19107.1870327 ms" // Linux PHP 7.3.11 (same linux box as above)

5) microtime + sprintf + DateTime::createFromFormat + DateTime->format:

$now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true)));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true))); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "79387.331962585 ms" // macOS PHP 5.6.30
string(18) "60734.437942505 ms" // Linux PHP 5.4.16
string(18) "18594.941139221 ms" // Linux PHP 7.3.11 (same linux box as above)

Here is another method that I find slightly more elegant/simple:

echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));

Based on @ArchCodeMonkey answer.

If you have declare(strict_types=1) you must cast second argument to string

enter image description here


As of PHP 7.1 you can simply do this:

$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );

It will display as:

04-11-2018 10:54:01.321688

// Procedural
$fineStamp = date('Y-m-d\TH:i:s') . substr(microtime(), 1, 9);
echo $fineStamp . PHP_EOL;

// Object-oriented (if you must). Still relies on $fineStamp though :-\
$d = new DateTime($fineStamp);
echo $d->format('Y-m-d\TH:i:s.u') . PHP_EOL;

if you are using Carbon, you can use the defined spec "RFC3339_EXTENDED". or customize it.

Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';

With PHP 7.0+ now here you can do the following:

$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));

This does the following in order:

  1. Trims the last 4 zeros off the string so Date() can handle the date.
  2. Uses date to format the milliseconds into a date time string that DateTime can understand.
  3. DateTime() can then allow you to modify the time zone you are in, but ensure that date_default_timezone_set("Timezone"); is set before you use DateTime() functions and classes.
  4. It is good practice to use a constructor in your classes to make sure your in the correct timezone when DateTime() classes or functions are used.

I'm use

echo date("Y-m-d H:i:s.").gettimeofday()["usec"];

output: 2017-09-05 17:04:57.555036

This is based on answer from ArchCodeMonkey.

But just simplified, if you just want something quick that works.

function DateTime_us_utc(){
    return DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
}
function DateTime_us(){
    $now = DateTime_us_utc();
    return $now->setTimeZone(new DateTimeZone(date_default_timezone_get()));
}

So for me then

$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");

Here's a slightly shorter approach. Rather than work to create a high-precision numeric date/time, I convert the microsecond value to a string, remove the 0, and add it to the end of the date/time string. I can easily trim the number of decimals by adjusting the string length parameter; here I use 4 to get milliseconds, but you could use 7 to get microseconds.

$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);

For a microtime() value of 0.98236000 1407400573, this returns 08-07-14 01:08:13.982.


For PHP 8.0+

The bug has been recently fixed and now you can use UNIX timestamps with a fractional part.

$milliseconds = 1375010774123;

$d = new DateTime( '@'. $milliseconds/1000 );
print $d->format("m-d-Y H:i:s.u");

Output:

07-28-2013 11:26:14.123000

For PHP < 8.0

You need to specify the format of your UNIX timestamp before you can use it in the DateTime object. As noted in other answers, you can simply work around this bug by using createFromFormat() and number_format()

$milliseconds = 1375010774123;

$d = DateTime::createFromFormat('U.v', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");

Output:

07-28-2013 11:26:14.123000

For PHP < 7.3

If you are still using PHP older than 7.3 you can replace U.v with U.u. It will not make any difference, but the millisecond format identifier is present only since PHP 7.3.

$milliseconds = 1375010774123;
//                                 V - Use microseconds instead of milliseconds
$d = DateTime::createFromFormat('U.u', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");

Output:

07-28-2013 11:26:14.123000


Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to date

How do I format {{$timestamp}} as MM/DD/YYYY in Postman? iOS Swift - Get the Current Local Time and Date Timestamp Typescript Date Type? how to convert current date to YYYY-MM-DD format with angular 2 SQL Server date format yyyymmdd Date to milliseconds and back to date in Swift Check if date is a valid one change the date format in laravel view page Moment js get first and last day of current month How can I convert a date into an integer?

Examples related to timestamp

concat yesterdays date with a specific time How do I format {{$timestamp}} as MM/DD/YYYY in Postman? iOS Swift - Get the Current Local Time and Date Timestamp Pandas: Convert Timestamp to datetime.date Spark DataFrame TimestampType - how to get Year, Month, Day values from field? What exactly does the T and Z mean in timestamp? What does this format means T00:00:00.000Z? Swift - iOS - Dates and times in different format Convert timestamp to string Timestamp with a millisecond precision: How to save them in MySQL

Examples related to milliseconds

Timestamp with a millisecond precision: How to save them in MySQL How to get milliseconds from LocalDateTime in Java 8 Converting milliseconds to minutes and seconds with Javascript How to convert time milliseconds to hours, min, sec format in JavaScript? Getting date format m-d-Y H:i:s.u from milliseconds Get DateTime.Now with milliseconds precision How to convert milliseconds to seconds with precision How to convert a string Date to long millseconds How can I get the count of milliseconds since midnight for the current? milliseconds to days