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

发布于 2024-09-18 17:28:45 字数 46 浏览 9 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

使用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)
}
*/

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)
}
*/
惜醉颜 2024-09-25 17:28:46

简短回答:

仅限 64 位平台!

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

[如果您运行 64 位 PHP,则常量 PHP_INT_SIZE 等于 8 > ]


长答案:

如果您首先想要一个以毫秒为单位的 time() 等效函数,您必须考虑到 time() 返回自“纪元时间”(01/01/1970),毫秒数,因为“纪元时间”是一个很大的数字,不适合 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 intval( $mt[1] * 1E3 ) + intval( round( $mt[0] * 1E3 ) );
}

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

0.90441300 1409263371

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

上面的函数 milliseconds() 将整数部分乘以 1000

1409263371000

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

1409263371904

请注意,两者$mt[1]round 的结果通过 intval() 转换为 int。这是必要的,因为它们是浮点型,并且在不进行强制转换的情况下对它们进行操作将导致函数返回一个精度有所损失的浮点型。

函数稍微精确一些,

round(microtime(true)*1000);

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


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

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

这与您获得的值相同

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

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

那么你可能有

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

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 ) );
}
七秒鱼° 2024-09-25 17:28:46

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

从您的评论来看,您似乎希望将其作为高精度 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);
}

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);
}
南…巷孤猫 2024-09-25 17:28:46

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

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

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

$milliseconds = date_create()->format('Uv');
灰色世界里的红玫瑰 2024-09-25 17:28:46

echo date('Ymd H:i:s.') 。 gettimeofday()['usec'];

输出:

2016-11-19 15:12:34.346351

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

output:

2016-11-19 15:12:34.346351

路弥 2024-09-25 17:28:46

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

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);
}
一生独一 2024-09-25 17:28:46

即使您使用的是 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

或者你可以使用好的单行代码:

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

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
眼角的笑意。 2024-09-25 17:28:46

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 

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 
滥情空心 2024-09-25 17:28:46

试试这个:

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

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"); 
}
镜花水月 2024-09-25 17:28:46
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

注意:由于以下功能的改进,此功能需要 PHP5
microtime() 和 bc 数学模块也是必需的(因为我们正在处理
如果数字较大,可以检查phpinfo中是否有该模块)。

希望这对您有帮助。

$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.

你又不是我 2024-09-25 17:28:46
$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
    ($the_date_time->format('u') / 1000);
$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
    ($the_date_time->format('u') / 1000);
浸婚纱 2024-09-25 17:28:46

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

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

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

function mstime(){
    $mstime = explode(' ',microtime());
    return $mstime[1].''.(int)($mstime[0]*1000);
}
满意归宿 2024-09-25 17:28:46

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

之后,微秒(true) > 给了我 1631882476.298437 的输出。

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

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

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);
    }
Bonjour°[大白 2024-09-25 17:28:46

我个人使用这个:

public static function formatMicrotimestamp(DateTimeInterface $dateTime): int
{
    return (int) substr($dateTime->format('Uu'), 0, 13);
}

I personaly use this:

public static function formatMicrotimestamp(DateTimeInterface $dateTime): int
{
    return (int) substr($dateTime->format('Uu'), 0, 13);
}
秋叶绚丽 2024-09-25 17:28:46

当获取毫秒时,我们期望看到 3 数字:

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

这本质上是 JavaScript 中实现的类似:

var milliseconds = (new Date()).getMilliseconds(); // e.g. 435

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
夏末的微笑 2024-09-25 17:28:46

使用这个:

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

再见

Use this:

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

Bye

生死何惧 2024-09-25 17:28:45

简短的回答是:

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

The short answer is:

$milliseconds = floor(microtime(true) * 1000);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文