microtime

(PHP 4, PHP 5, PHP 7, PHP 8)

microtime返回当前 Unix 时间戳和微秒数

说明

microtime(bool $as_float = false): string|float

microtime() 返回当前 Unix 时间戳以及微秒数。本函数仅在支持 gettimeofday() 系统调用的操作系统下可用。

对于性能测量,建议使用 hrtime()

参数

as_float

如果使用并设置为 truemicrotime() 将返回浮点数而不是字符串,具体查看下面的返回值相关描述。

返回值

默认情况下,microtime() 返回“msec sec”形式的 string,其中 sec 是自 Unix 纪元(格林威治标准时间 1970 年 1 月 1 日 0:00:00)以来的秒数,msec 是自 sec 以来经过的微秒,表示为秒数的小数部分。

如果 as_float 设置为 true,然后 microtime() 返回 float,表示自 Unix 纪元以来的当前时间,以秒为单位,精确到最接近的微秒。

示例

示例 #1 计时脚本执行时间

<?php
$time_start
= microtime(true);

// Sleep 一会
usleep(100);

$time_end = microtime(true);
$time = $time_end - $time_start;

echo
"Did nothing in $time seconds\n";
?>

示例 #2 microtime()REQUEST_TIME_FLOAT

<?php
// 随机 sleep 时间
usleep(mt_rand(100, 10000));

// 在 $_SERVER 超全局数组中 REQUEST_TIME_FLOAT 是有效的。
// 包含请求开始的时间戳,精度为微秒。
$time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];

echo
"Did nothing in $time seconds\n";
?>

参见

  • time() - 返回当前的 Unix 时间戳
  • hrtime() - 获取系统的高精度时间

add a note add a note

User Contributed Notes 20 notes

up
153
Russell G.
11 years ago
Note that the timestamp returned is "with microseconds", not "in microseconds". This is especially good to know if you pass 'true' as the parameter and then calculate the difference between two float values -- the result is already in seconds; it doesn't need to be divided by a million.
up
174
player27
11 years ago
You can use one variable to check execution $time as follow:

<?php
$time
= -microtime(true);
$hash = 0;
for (
$i=0; $i < rand(1000,4000); ++$i) {
   
$hash ^= md5(substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, rand(1,10)));
}
$time += microtime(true);
echo
"Hash: $hash iterations:$i time: ",sprintf('%f', $time),PHP_EOL;
?>
up
47
jamie at bishopston dot net
13 years ago
All these timing scripts rely on microtime which relies on gettimebyday(2)

This can be inaccurate on servers that run ntp to syncronise the servers
time.

For timing, you should really use clock_gettime(2) with the
CLOCK_MONOTONIC flag set.

This returns REAL WORLD time, not affected by intentional clock drift.

This may seem a bit picky, but I recently saw a server that's clock was an
hour out, and they'd set it to 'drift' to the correct time (clock is speeded
up until it reaches the correct time)

Those sorts of things can make a real impact.

Any solutions, seeing as php doesn't have a hook into clock_gettime?

More info here: http://tinyurl.com/28vxja9

http://blog.habets.pp.se/2010/09/
gettimeofday-should-never-be-used-to-measure-time
up
12
shdwlynxjunk at yahoo dot com
4 years ago
It is important to note that microtime(TRUE) does NOT always return a float (at least in PHP 5.x; I have not tested 7.x).  If it happens to land on an exact second, it returns an integer instead.

Here is some simple code to illustrate this:
<?php
   
for ($i = 0; $i < 5000; $i++) {
      echo
microtime(TRUE) . "\n";
     
usleep(100); // Adjust this if your PC is too fast/slow
   
}
?>

When you run this at a command line, you'll see output like this (and you'll know EXACTLY when I ran this):
1588881290.9992
1588881290.9994
1588881290.9996
1588881290.9998
1588881291           <-- Look, Ma, an integer!
1588881291.0002
1588881291.0004
1588881291.0006
1588881291.0008

Why does this matter?  Because if you want to format microtime into a very friendly but exact date/time, this popular code will fail on exact seconds (but works great otherwise):

<?php
   $raw_time
= DateTime::createFromFormat('U.u', microtime(TRUE)); // This line will not create an object when microtime returns an integer because it depends on the number being a float, including a decimal point!
  
$today = $raw_time->format('Y-m-d H:i:s.u'); // This will die when format is attempted on a non-object
?>

The fix is to format the microtime output to force it to always be a float:
<?php
   $utime
= sprintf('%.4f', microtime(TRUE));
  
$raw_time = DateTime::createFromFormat('U.u', $utime);
  
$today = $raw_time->format('Y-m-d H:i:s.u');
?>

Paraphrasing the characters on Silicon Valley, "Always Float! Always Float!  Always Float!"
up
23
radek at pinkbike com
18 years ago
A lot of the comments here suggest adding in the following way:  (float)$usec + (float)$sec
Make sure you have the float precision high enough as with the default precision of 12, you are only precise to the 0.01 seconds. 
Set this in you php.ini file.
        precision    =  16
up
2
aldemarcalazans at gmail dot com
3 years ago
The description of "msec", in this documentation, is very bad.

It is NOT the microseconds that have elapsed since "sec" (if so, it should be given as an integer, without the "0." in the beginning of the string).
It IS the fractional part of the time elapsed since "sec", with microseconds (10E-6) precision, if the last "00" are not considered significant".
If the last two digits are significant, then we would have a precision of 10E-8 seconds.
up
8
luke at lucanos dot com
16 years ago
Rather than using the list() function, etc. I have found the following code to be a bit cleaner and simpler:
<?php
$theTime
= array_sum( explode( ' ' , microtime() ) );
echo
$theTime;
# Displays "1212018372.3366"
?>
up
1
Carlos Reche
5 years ago
As previously pointed out, setting the parameter $get_as_float as true will not allow microseconds precision (what would mean 6 decimal digits). It happens because the float returned has a big integer section, what crops the decimal one leaving it with less than 6 digits.

Here is a solution to easily calculate the execution time of a script without having to alter any configuration parameter. It uses the former way of getting microseconds.

<?php

class Timer {

    private
$timeStart;
    private
$microsecondsStart;
    private
$timeStop;
    private
$microsecondsStop;

    public function
__construct() {
       
$this->start();
    }

    public function
start(): void {
        [
$this->microsecondsStart, $this->timeStart] = explode(' ', microtime());
       
$timeStop         = null;
       
$microsecondsStop = null;
    }

    public function
stop(): void {
        [
$this->microsecondsStop, $this->timeStop] = explode(' ', microtime());
    }

    public function
getTime(): float {
       
$timeEnd         = $this->timeStop;
       
$microsecondsEnd = $this->microsecondsStop;
        if (!
$timeEnd) {
            [
$microsecondsEnd, $timeEnd] = explode(' ', microtime());
        }

       
$seconds      = $timeEnd - $this->timeStart;
       
$microseconds = $microsecondsEnd - $this->microsecondsStart;

       
// now the integer section ($seconds) should be small enough
        // to allow a float with 6 decimal digits
       
return round(($seconds + $microseconds), 6);
    }
}

$t = new Timer();
usleep(250);
echo
$t->getTime();

?>
up
8
gomodo at free dot fr
15 years ago
Need a mini benchmark ?
Use microtime with this (very smart) benchmark function :

mixed mini_bench_to(array timelist[, return_array=false])
return a mini bench result

-the timelist first key must be 'start'
-default return a resume string, or array if return_array= true :
'total_time' (ms) in first row
details (purcent) in next row

example :
<?php
unset($t);    // if previous used

//-- zone to bench
$t['start'] = microtime(true);
$tab_test=array(1,2,3,4,5,6,7,8);
$fact=1;
$t['init_values'] = microtime(true);
foreach (
$tab_test as $key=>$value)
{
   
$fact=$fact*$value;
}
$t['loop_fact'] = microtime(true);
echo
"fact = ".$fact."\n";
//-- END zone to bench

echo "---- string result----\n";
$str_result_bench=mini_bench_to($t);
echo
$str_result_bench; // string return
echo "---- tab result----\n";
$tab_result_bench=mini_bench_to($t,true);
echo
var_export($tab_result_bench,true);
?>
this example return:

---- string result----
total time : 0.0141 ms
start -> init_values : 51.1 %
init_values -> loop_fact : 48.9 %
---- tab result----
array (
  'total_time' => 0.0141,
  'start -> init_values' => 51.1,
  'init_values -> loop_fact' => 48.9,
)

The function to include :

<?php
function mini_bench_to($arg_t, $arg_ra=false)
  {
   
$tttime=round((end($arg_t)-$arg_t['start'])*1000,4);
    if (
$arg_ra) $ar_aff['total_time']=$tttime;
    else
$aff="total time : ".$tttime."ms\n";
   
$prv_cle='start';
   
$prv_val=$arg_t['start'];

    foreach (
$arg_t as $cle=>$val)
    {
        if(
$cle!='start')   
        {
           
$prcnt_t=round(((round(($val-$prv_val)*1000,4)/$tttime)*100),1);
            if (
$arg_ra) $ar_aff[$prv_cle.' -> '.$cle]=$prcnt_t;
           
$aff.=$prv_cle.' -> '.$cle.' : '.$prcnt_t." %\n";
           
$prv_val=$val;
           
$prv_cle=$cle;
        }
    }
    if (
$arg_ra) return $ar_aff;
    return
$aff;
  }
?>
up
1
joe from wonderland org
6 years ago
A convenient way to write the current time / microtime as formatted string in your timezone as expression?

<?php
$nowDate
= 'DateTime  now is: ' . (new \DateTime(null,(new \DateTimeZone('Europe/Berlin'))))->format('Y-m-d H:i:s');

$microDate = 'Microtime now is: ' . date_create_from_format( 'U.u', number_format(microtime(true), 6, '.', ''))->setTimezone((new \DateTimeZone('Europe/Berlin')))->format('ymd H:i:s.u e');
?>

For the microtime expression only the procedural style can be used. If you do not use namespaces the backslashes may be removed.
PHP >= 5.4 needed due to accessing a member of a newly created object in a single expression "(new DateTime())->format('Y-m-d H:i:s.u')"

DateTime  now is: 2018-06-01 14:54:58 Europe/Berlin
Microtime now is: 180601 14:54:58.781716 Europe/Berlin
up
1
how to set nonce value with microtime
7 years ago
Using microtime() to set 'nonce' value:

ini_set("precision", 16);
$nonce="nonce=".microtime(true)/0.000001;
up
1
Daniel Rhodes
11 years ago
But note that the default 'precision' setting of PHP* - which is used when a float is converted to a stringy format by echo()ing, casting or json_encode()ing etc - is not enough to hold the six digit accuracy of microtime(true).

Out of the box, microtime(true) will echo something like:

1377611450.1234

Which is obviously less than microsecond accuracy. You'll probably want to bump the 'precision' setting up to 16 which will echo something like:

1377611450.123456

*Internally* it will be accurate to the six digits even with the default 'precision', but a lot of things (ie. NoSQL databases) are moving to all-text representations these days so it becomes a bit more important.

* 14 at the time of writing
up
1
langpavel at phpskelet dot org
13 years ago
I use this for measure duration of script execution. This function should be defined (and of couse first call made) as soon as possible.

<?php
/**
* get execution time in seconds at current point of call in seconds
* @return float Execution time at this point of call
*/
function get_execution_time()
{
    static
$microtime_start = null;
    if(
$microtime_start === null)
    {
       
$microtime_start = microtime(true);
        return
0.0;
    }   
    return
microtime(true) - $microtime_start;
}
get_execution_time();

?>

However it is true that result depends of gettimeofday() call. ([jamie at bishopston dot net] wrote this & I can confirm)
If system time change, result of this function can be unpredictable (much greater or less than zero).
up
2
zital at riseup dot net
3 years ago
<?php
//timestamp in milliseconds:
intval(microtime(true)*1000)

//timestamp in microseconds:
intval(microtime(true)*1000*1000)

//timestamp in nanoseconds:
intval(microtime(true)*1000*1000*1000)
up
1
Robin Leffmann
13 years ago
While doing some experiments on using microtime()'s output for an entropy generator I found that its microsecond value was always quantified to the nearest hundreds (i.e. the number ends with 00), which affected the randomness of the entropy generator. This output pattern was consistent on three separate machines, running OpenBSD, Mac OS X and Windows.

The solution was to instead use gettimeofday()'s output, as its usec value followed no quantifiable pattern on any of the three test platforms.
up
0
thomas
12 years ago
I have been getting negative values substracting a later microtime(true) call from an earlier microtime(true) call on Windows with PHP 5.3.8

Produces negative values
------------------------------
for($i = 0; $i<100; $i++) {
    $x =  microtime(true);
    //short calculation
    $y = microtime(true);
    echo ($y-$x) . "\n"; // <--- mostly negatives
}

Calling usleep(1) seems to work
---------------------------------------
for($i = 0; $i<100; $i++) {
    $x =  microtime(true);
    //short calculation
    usleep(1);
    $y = microtime(true);
    echo ($y-$x) . "\n"; // <--- fixed now
}
up
0
vladson at pc-labs dot info
19 years ago
I like to use bcmath for it
<?php
function micro_time() {
   
$temp = explode(" ", microtime());
    return
bcadd($temp[0], $temp[1], 6);
}

$time_start = micro_time();
sleep(1);
$time_stop = micro_time();

$time_overall = bcsub($time_stop, $time_start, 6);
echo
"Execution time - $time_overall Seconds";
?>
up
-2
EdorFaus
18 years ago
Of the methods I've seen here, and thought up myself, to convert microtime() output into a numerical value, the microtime_float() one shown in the documentation proper(using explode,list,float,+) is the slowest in terms of runtime.

I implemented the various methods, ran each in a tight loop 1,000,000 times, and compared runtimes (and output). I did this 10 times to make sure there wasn't a problem of other things putting a load spike on the server. I'll admit I didn't take into account martijn at vanderlee dot com's comments on testing accuracy, but as I figured the looping code etc would be the same, and this was only meant as a relative comparison, it should not be necessary.

The above method took on average 5.7151877 seconds, while a method using substr and simply adding strings with . took on average 3.0144226 seconds. rsalazar at innox dot com dot mx's method using preg_replace used on average 4.1819633 seconds. This shows that there are indeed differences, but for normal use noone is going to notice it.

Note that the substr method mentioned isn't quite the one given anonymously below, but one I made based on it:
<?php
$time
=microtime();
$timeval=substr($time,11).substr($time,1,9);
?>

Also worth noting is that the microtime_float() method gets faster, and no less accurate, if the (float) conversions are taken out and the variables are simply added together.

Any of the methods that used + or array_sum ended up rounding the result to 2 digits after the decimal point, while (most of) the ones using preg_replace or substr and . kept all the digits.

For accurate timing, since floating-point arithmetic would lose precision, I stored microtime results as-is and calculated time difference with this function:
<?php
function microtime_used($before,$after) {
    return (
substr($after,11)-substr($before,11))
        +(
substr($after,0,9)-substr($before,0,9));
}
?>

For further information, the script itself, etc, see http://edorfaus.xepher.net/div/convert-method-test.php
up
-5
Nads
11 years ago
Get date time with milliseconds

$micro_date = microtime();
$date_array = explode(" ",$micro_date);
$date = date("Y-m-d H:i:s",$date_array[1]);
echo "Date: $date:" . $date_array[0];

Test accuracy by running it in a loop.
up
-8
johovich at yandex dot ru
7 years ago
//Function to convert microtime return to human readable units
//функция для конвертации времени, принимает значения в секундах

function convert_time($time)
{
    if($time == 0 ){
        return 0;
    }
    //допустимые единицы измерения
    $unit=array(-4=>'ps', -3=>'ns',-2=>'mcs',-1=>'ms',0=>'s');
    //логарифм времени в сек по основанию 1000
    //берем значение не больше 0, т.к. секунды у нас последняя изменяемая по тысяче величина, дальше по 60
    $i=min(0,floor(log($time,1000)));

    //тут делим наше время на число соответствующее единицам измерения т.е. на миллион для секунд,
    //на тысячу для миллисекунд
    $t = @round($time/pow(1000,$i) , 1);
    return $t.$unit[$i];
}
To Top