How to get current time in milliseconds in PHP?
Asked Answered
U

17

422

time() is in seconds - is there one in milliseconds?

Unreflecting answered 7/9, 2010 at 7:48 Comment(0)
P
660

The short answer is:

$milliseconds = floor(microtime(true) * 1000);
Piker answered 11/7, 2012 at 2:20 Comment(11)
@FredrikWendt, I think you are confusing with time(). microtime(true) on the other hand returns the current time in seconds since the Unix epoch accurate to the nearest microsecond (see PHP reference). It's actually very easy to test if you run the above code in a loop and display the milliseconds.Piker
You should take only first 13 digits, otherwise you might get a floating number in ~90%: substr(microtime(true) * 1000, 0, 13);Lordsandladies
Shouldn't that be microtime(true) / 1000 (division instead of mulitplication)?Stoneblind
@JordanLev, it should be multiplication because microtime(true) returns the Unix timestamp in seconds as a float.Piker
I really like this solution. Also suitable for microbenchmarking in case it does not have to be too accurate. Helped me a lot finding the bottleneck in my software.Cruel
@user25163 You are not absolutely right. If you expect timestamp before "Mon, 31 Oct 1966 14:13:21 GMT" and after "Sat, 20 Nov 2286 17:46:39 GMT" it will be more than 13 digitsNacreous
I do not like the response from this.It's: 1.51196274127E+12Amye
I don't think you need to round, as microtime(true) only returns 4 decimals (PHP v 7.1.16)?Timepiece
Faster and probably precise enough for most people is (int)(microtime(true)*1000)Honorine
Not only is (int)(microtime(true)*1000) faster, it's also more correct; with round you can end up 0.5ms in the future, with a nasty effect of -1ms time difference somewhere ;-)Cartercarteret
I have changed to floor() which indeed prevents the date from being in the future.Piker
A
111

Use microtime. This function returns a string separated by a space. The first part is the fractional part of seconds, the second part is the integral part. Pass in true to get as a number:

var_dump(microtime());       // string(21) "0.89115400 1283846202"
var_dump(microtime(true));   // float(1283846202.89)

Beware of precision loss if you use microtime(true).

There is also gettimeofday that returns the microseconds part as an integer.

var_dump(gettimeofday());
/*
array(4) {
  ["sec"]=>
  int(1283846202)
  ["usec"]=>
  int(891199)
  ["minuteswest"]=>
  int(-60)
  ["dsttime"]=>
  int(1)
}
*/
Arm answered 7/9, 2010 at 7:50 Comment(9)
So generally speaking microtime() equals 1000*time(),right?Unreflecting
I see,there can be errors,but the error should be less than 1000,right?Unreflecting
@COMer: Which variant you are talking about?Arm
microtime(true) and 1000*time()Unreflecting
@COMer: 1000*time() won't give you milliseconds. microtime(true) returns a float which has 14 digits of precision. The seconds part already took 10, so that left 4 digits for the microseconds part. This should be enough since milliseconds only require 3 extra digits.Arm
according to php documentation the get_as_float parameter was not available prior to version 5.0.0Hotblooded
I'm very impressed that you ran all 3 within a microsecond! What server specs are those? :DGaribull
When running var_dump(microtime(true));, my php (7.1.16) returns 4 decimals: float(1523522152.2452). Possibly the last two digits were 0 in your case and therefore not shown?Timepiece
@COMer: Based on other answers in this page, microtime(true) returns the timestamp since the Unix epoch in seconds. That said, I don't think this statement is wholly accurate though, since microtime(true) return value can have decimal digits, so it's not exactly integer seconds since the Unix epoch.Nutter
M
66

Short answer:

64 bits platforms only!

function milliseconds() {
    $mt = explode(' ', microtime());
    return intval( $mt[1] * 1E3 ) + intval( round( $mt[0] * 1E3 ) );
}

[ If you are running 64 bits PHP then the constant PHP_INT_SIZE equals to 8 ]


Long answer:

If you want an equilvalent function of time() in milliseconds first you have to consider that as time() returns the number of seconds elapsed since the "epoch time" (01/01/1970), the number of milliseconds since the "epoch time" is a big number and doesn't fit into a 32 bits integer.

The size of an integer in PHP can be 32 or 64 bits depending on platform.

From http://php.net/manual/en/language.types.integer.php

The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18, except for Windows, which is always 32 bit. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5.

If you have 64 bits integers then you may use the following function:

function milliseconds() {
    $mt = explode(' ', microtime());
    return intval( $mt[1] * 1E3 ) + intval( round( $mt[0] * 1E3 ) );
}

microtime() returns the number of seconds since the "epoch time" with precision up to microseconds with two numbers separated by space, like...

0.90441300 1409263371

The second number is the seconds (integer) while the first one is the decimal part.

The above function milliseconds() takes the integer part multiplied by 1000

1409263371000

then adds the decimal part multiplied by 1000 and rounded to 0 decimals

1409263371904

Note that both $mt[1] and the result of round are casted to int via intval(). This is necessary because they are floats and the operation on them without casting would result in the function returning a float with a loss in precision.

Finally, that function is slightly more precise than

round(microtime(true)*1000);

that with a ratio of 1:10 (approx.) returns 1 more millisecond than the correct result. This is due to the limited precision of the float type (microtime(true) returns a float). Anyway if you still prefer the shorter round(microtime(true)*1000); I would suggest casting to int the result.


Even if it's beyond the scope of the question it's worth mentioning that if your platform supports 64 bits integers then you can also get the current time in microseconds without incurring in overflow.

If fact 2^63 - 1 (biggest signed integer) divided by 10^6 * 3600 * 24 * 365 (approximately the microseconds in one year) gives 292471.

That's the same value you get with

echo intdiv( PHP_INT_MAX, 1E6 * 3600 * 24 * 365 );

In other words, a signed 64 bits integer have room to store a timespan of over 200,000 years measured in microseconds.

You may have then

function microseconds() {
    $mt = explode(' ', microtime());
    return intval( $mt[1] * 1E6 ) + intval( round( $mt[0] * 1E6 ) );
}
Maelstrom answered 28/8, 2014 at 23:14 Comment(3)
why not just: ` function getMilliEpoch(){ $mt = explode(' ', microtime()); return $mt[1] . substr($mt[0], 0, 5) * 1000; }`Southward
Now there is a parameter for microtime function, if it is set to true, it's return the seconds and milliseconds since 1st of january in 1970, 0 hour 0 minutes 0 seconds as float. Here is an example: microtime(true) // 1553260455.7242Enswathe
@Enswathe yes, but due to limited precision of the float type, calculating the number of millicesonds from microtime(true) will result in a slightly inaccurate valueMaelstrom
H
49

As other have stated, you can use microtime() to get millisecond precision on timestamps.

From your comments, you seem to want it as a high-precision UNIX Timestamp. Something like DateTime.Now.Ticks in the .NET world.

You may use the following function to do so:

function millitime() {
  $microtime = microtime();
  $comps = explode(' ', $microtime);

  // Note: Using a string here to prevent loss of precision
  // in case of "overflow" (PHP converts it to a double)
  return sprintf('%d%03d', $comps[1], $comps[0] * 1000);
}
Henghold answered 7/9, 2010 at 8:20 Comment(1)
Is not it return the server time? In my case I see the stored time in db is my local browser time. Suppose, my sever timezone is EST+3 and my browser time is GMT+6, While I submit a form from GMT+6 location, I see the stored time is GMT+6 time equivalent millisecond. So, What is the problem? :(Kino
A
34

Shortest version of string variant (32-bit compatibile):

$milliseconds = date_create()->format('Uv');
Arber answered 17/9, 2021 at 7:43 Comment(2)
This one-liner should have more votes.Credits
Yes, very true. Seems not only easier to read but also safer in terms of mixing up whether to divide or multiply by 1,000Retrocede
S
17

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

output:

2016-11-19 15:12:34.346351

Siliqua answered 19/11, 2016 at 14:16 Comment(2)
This uses the same timestamp: $t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec'];Landon
microseconds should be zero padded: $timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);Medieval
I
14

Use microtime(true) in PHP 5, or the following modification in PHP 4:

array_sum(explode(' ', microtime()));

A portable way to write that code would be:

function getMicrotime()
{
    if (version_compare(PHP_VERSION, '5.0.0', '<'))
    {
        return array_sum(explode(' ', microtime()));
    }

    return microtime(true);
}
Islamism answered 7/9, 2010 at 10:23 Comment(0)
D
10

This works even if you are on 32-bit PHP:

list($msec, $sec) = explode(' ', microtime());

$time_milli = $sec.substr($msec, 2, 3); // '1491536422147'
$time_micro = $sec.substr($msec, 2, 6); // '1491536422147300'

Note this doesn't give you integers, but strings. However this works fine in many cases, for example when building URLs for REST requests.


If you need integers, 64-bit PHP is mandatory.

Then you can reuse the above code and cast to (int):

list($msec, $sec) = explode(' ', microtime());

// these parentheses are mandatory otherwise the precedence is wrong!
//                  ↓                        ↓
$time_milli = (int) ($sec.substr($msec, 2, 3)); // 1491536422147
$time_micro = (int) ($sec.substr($msec, 2, 6)); // 1491536422147300

Or you can use the good ol' one-liners:

$time_milli = (int) round(microtime(true) * 1000);    // 1491536422147
$time_micro = (int) round(microtime(true) * 1000000); // 1491536422147300
Dynamometer answered 7/4, 2017 at 4:20 Comment(0)
S
9

PHP 5.2.2 <

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

PHP 7.0.0 < 7.1

$d = new DateTime();
echo $d->format("Y-m-d H:i:s.v"); // v : Milliseconds 
Scaffolding answered 9/10, 2019 at 10:26 Comment(1)
In php <7.1 new DateTime() microseconds are always 0 see php.net/manual/en/migration71.incompatible.php.Medieval
B
8

try this:

public function getTimeToMicroseconds() {
    $t = microtime(true);
    $micro = sprintf("%06d", ($t - floor($t)) * 1000000);
    $d = new DateTime(date('Y-m-d H:i:s.' . $micro, $t));

    return $d->format("Y-m-d H:i:s.u"); 
}
Basophil answered 16/11, 2015 at 8:45 Comment(0)
N
6
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

NOTE: PHP5 is required for this function due to the improvements with microtime() and the bc math module is also required (as we’re dealing with large numbers, you can check if you have the module in phpinfo).

Hope this help you.

Nibelung answered 7/9, 2010 at 7:48 Comment(0)
K
6
$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
    ($the_date_time->format('u') / 1000);
Kamakura answered 30/7, 2015 at 9:56 Comment(3)
Is that actually like padding three zeroes to the right?Ricketts
Not at all. It convert both part to milliseconds and give the sum. So it is more accurate than add zeros.Kamakura
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations!Taw
P
0

This is my implementation, should work on 32bit as well.

function mstime(){
    $mstime = explode(' ',microtime());
    return $mstime[1].''.(int)($mstime[0]*1000);
}
Precautionary answered 15/9, 2021 at 23:0 Comment(0)
O
0

If you want to see real microseconds, you will need to change the precision setting in php.ini to 16.

After that, microsecond(true) gave me the output of 1631882476.298437.

So I thought that I need to divide the remainder (298437) with 1000, but in fact, the remainder is 0.298437 of a second. So I need to multiply that by 1000 to get the correct result.

    function get_milliseconds()
    {
        $timestamp = microtime(true);
        return (int)(($timestamp - (int)$timestamp) * 1000);
    }
Otila answered 17/9, 2021 at 12:50 Comment(0)
S
0

I personaly use this:

public static function formatMicrotimestamp(DateTimeInterface $dateTime): int
{
    return (int) substr($dateTime->format('Uu'), 0, 13);
}
Spike answered 23/5, 2022 at 11:19 Comment(1)
why not just $dateTime->format('Uv') ?Attractant
C
0

When getting milliseconds we expect to see 3 digits:

$milliseconds = round(microtime(true) * 1000) % 1000; // e.g. 435

which is essentially an analogue of the implementation in JavaScript:

var milliseconds = (new Date()).getMilliseconds(); // e.g. 435
Celestina answered 17/10, 2023 at 10:48 Comment(0)
M
-4

Use this:

function get_millis(){
  list($usec, $sec) = explode(' ', microtime());
  return (int) ((int) $sec * 1000 + ((float) $usec * 1000));
}

Bye

Margotmargrave answered 7/9, 2013 at 10:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.