如何在 PHP 中以毫秒为单位获取当前时间?

Posted

技术标签:

【中文标题】如何在 PHP 中以毫秒为单位获取当前时间?【英文标题】:How to get current time in milliseconds in PHP? 【发布时间】:2011-04-09 01:47:24 【问题描述】:

time() 以秒为单位 - 有以毫秒为单位的吗?

【问题讨论】:

【参考方案1】:

简短的回答是:

$milliseconds = round(microtime(true) * 1000);

【讨论】:

@FredrikWendt,我认为您对time() 感到困惑。另一方面,microtime(true) 以秒为单位返回自 Unix 纪元以来的当前时间,精确到最接近的微秒(请参阅 php 参考)。如果你循环运行上面的代码并显示毫秒,实际上很容易测试。 我喜欢简短的回答。 你应该只取前 13 位数字,否则你可能会得到一个大约 90% 的浮点数:substr(microtime(true) * 1000, 0, 13); 不应该是microtime(true) / 1000(除法而不是乘法)吗? @JordanLev,它应该是乘法,因为 microtime(true) 以 为单位返回 Unix 时间戳作为浮点数。【参考方案2】:

使用microtime。此函数返回一个由空格分隔的字符串。第一部分是秒的小数部分,第二部分是整数部分。传入true 以获取数字:

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

如果使用microtime(true),请注意精度损失。

还有gettimeofday 将微秒部分作为整数返回。

var_dump(gettimeofday());
/*
array(4) 
  ["sec"]=>
  int(1283846202)
  ["usec"]=>
  int(891199)
  ["minuteswest"]=>
  int(-60)
  ["dsttime"]=>
  int(1)

*/

【讨论】:

所以一般来说microtime()等于1000*time(),对吧? 我明白了,可能会有错误,但错误应该小于1000,对吧? @COMer:你说的是哪个变种? microtime(true)1000*time() @COMer: 1000*time() 不会给你毫秒。 microtime(true) 返回具有 14 位精度的 float。秒部分已经用了 10,所以微秒部分剩下 4 个数字。这应该足够了,因为毫秒只需要 3 个额外的数字。【参考方案3】:

简答:

仅限 64 位平台!

function milliseconds() 
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000 + ((int)round($mt[0] * 1000));

[ 如果你运行的是 64 位 PHP,那么常量 PHP_INT_SIZE 等于 8 ]


长答案:

如果您首先想要以毫秒为单位的time() 的等效函数,您必须考虑,因为time() 返回自“纪元时间”(1970 年 1 月 1 日)以来经过的秒数,毫秒,因为“纪元时间”是一个很大的数字,不适合 32 位整数。

PHP 中整数的大小可以是 32 位或 64 位,具体取决于平台。

来自http://php.net/manual/en/language.types.integer.php

整数的大小取决于平台,尽管通常值约为 20 亿的最大值(即 32 位有符号)。 64 位平台的最大值通常约为 9E18,但 Windows 除外,它始终为 32 位。 PHP 不支持无符号整数。自 PHP 4.4.0 和 PHP 5.0.5 起,可以使用常量 PHP_INT_SIZE 确定整数大小,使用常量 PHP_INT_MAX 确定最大值。

如果你有 64 位整数,那么你可以使用以下函数:

function milliseconds() 
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000 + ((int)round($mt[0] * 1000));

microtime() 返回自“纪元时间”以来的秒数,精度可达微秒,两个数字用空格分隔,如...

0.90441300 1409263371

第二个数字是秒(整数),而第一个是小数部分。

上述函数milliseconds()取整数部分乘以1000

1409263371000

然后加上小数部分乘以1000并四舍五入到小数点0

1409263371904

注意$mt[1]round 的结果都被转换为int。这是必要的,因为它们是 floats,并且在没有强制转换的情况下对它们进行操作会导致函数返回 float

最后,这个函数比

更精确一点
round(microtime(true)*1000);

比例为 1:10(大约)的结果比正确结果多返回 1 毫秒。 这是由于浮点类型的精度有限(microtime(true) 返回浮点数)。 无论如何,如果您仍然喜欢较短的round(microtime(true)*1000);,我建议您将结果转换为int


即使超出了问题的范围,值得一提的是,如果您的平台支持 64 位整数,那么您也可以以微秒为单位获取当前时间,而不会导致溢出。

如果事实2^63 - 1(最大有符号整数)除以10^6 * 3600 * 24 * 365(大约一年中的微秒)得到292471

这与您获得的价值相同

echo (int)( PHP_INT_MAX / ( 1000000 * 3600 * 24 * 365 ) );

换句话说,一个有符号的 64 位整数有空间存储超过 200,000 年的时间跨度(以微秒为单位)。

那时你可能有

function microseconds() 
    $mt = explode(' ', microtime());
    return ((int)$mt[1]) * 1000000 + ((int)round($mt[0] * 1000000));

【讨论】:

为什么不只是:`function getMilliEpoch() $mt = explode(' ', microtime());返回 $mt[1] 。 substr($mt[0], 0, 5) * 1000; ` 现在有一个microtime函数的参数,如果设置为true,则返回1970年1月1日以来的秒数和毫秒数,0小时0分0秒为浮点数。这是一个例子: microtime(true) // 1553260455.7242 @kukko 是的,但是由于浮点类型的精度有限,从 microtime(true) 计算毫秒数会导致 值稍微不准确【参考方案4】:

正如其他人所说,您可以使用microtime() 获得时间戳的毫秒精度。

从您的 cmets 来看,您似乎希望它作为一个高精度的 UNIX 时间戳。 .NET 世界中的 DateTime.Now.Ticks 之类的东西。

您可以使用以下函数来做到这一点:

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);

【讨论】:

不是返回服务器时间吗?就我而言,我看到存储在 db 中的时间是我的本地浏览器时间。假设,我的服务器时区是 EST+3,我的浏览器时间是 GMT+6,当我从 GMT+6 位置提交表单时,我看到存储的时间是 GMT+6 时间等效毫秒。那么,问题是什么? :(【参考方案5】:

在 PHP 5 中使用 microtime(true),或者在 PHP 4 中进行如下修改:

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

编写该代码的可移植方式是:

function getMicrotime()

    if (version_compare(PHP_VERSION, '5.0.0', '<'))
    
        return array_sum(explode(' ', microtime()));
    

    return microtime(true);

【讨论】:

【参考方案6】:

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

输出:

2016-11-19 15:12:34.346351

【讨论】:

这使用相同的时间戳:$t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec']; 微秒应补零:$timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);【参考方案7】:

即使您使用的是 32 位 PHP,也可以使用:

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

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

注意这不是给你整数,而是字符串。但是,这在许多情况下都可以正常工作,例如在为 REST 请求构建 URL 时。

如果需要整数,则必须使用 64 位 PHP。

那么就可以重用上面的代码并强制转换为(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

或者你可以使用好的 ol' one-liners:

$time_milli = (int) round(microtime(true) * 1000);    // 1491536422147
$time_micro = (int) round(microtime(true) * 1000000); // 1491536422147300

【讨论】:

【参考方案8】:

试试这个:

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"); 

【讨论】:

【参考方案9】:

PHP 5.2.2

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

PHP 7.0.0

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

【讨论】:

在 php php.net/manual/en/migration71.incompatible.php.【参考方案10】:
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

注意:此功能需要 PHP5,因为 microtime() 和 bc 数学模块也是必需的(因为我们正在处理 数量大的可以检查phpinfo中是否有模块)。

希望对您有所帮助。

【讨论】:

【参考方案11】:
$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
    ($the_date_time->format('u') / 1000);

【讨论】:

这实际上是像在右边填充三个零吗? 一点也不。它将这两个部分都转换为毫秒并给出总和。所以比加零更准确。 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性!【参考方案12】:

字符串变体的最短版本(32 位兼容):

$milliseconds = date_create()->format('Uv');

【讨论】:

这个单行应该有更多的票数。【参考方案13】:

如果您想查看真正的微秒,您需要将 php.ini 中的 precision 设置更改为 16。

之后,microsecond(true) 给了我1631882476.298437 的输出。

所以我认为我需要将余数(298437除以 1000,但实际上余数是 0.298437一秒。所以我需要将它乘以 1000 才能得到正确的结果。

    function get_milliseconds()
    
        $timestamp = microtime(true);
        return (int)(($timestamp - (int)$timestamp) * 1000);
    

【讨论】:

【参考方案14】:

这是我的实现,应该也可以在 32 位上运行。

function mstime()
    $mstime = explode(' ',microtime());
    return $mstime[1].''.(int)($mstime[0]*1000);

【讨论】:

【参考方案15】:

使用这个:

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

再见

【讨论】:

以上是关于如何在 PHP 中以毫秒为单位获取当前时间?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ruby 中以毫秒为单位计时?

如何在 c++ 中以毫秒为单位获得系统启动时间?

如何以毫秒为单位获取当前时间?

如何像 Java 一样获取自 1970 年以来的当前时间戳(以毫秒为单位)

如何在PHP中以分钟为单位获取时差

如何以毫秒为单位获取firebase服务器的当前时间戳?