簡體   English   中英

如何在 PHP 中以毫秒為單位獲取當前時間?

[英]How to get current time in milliseconds in PHP?

time()以秒為單位 - 以毫秒為單位嗎?

簡短的回答是:

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

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

簡短的回答:

僅限 64 位平台!

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

[如果您運行的是 64 位 PHP,那么常量PHP_INT_SIZE等於8 ]


長答案:

如果您首先想要一個以毫秒為單位的time()等效函數,則必須考慮到time()返回自“紀元時間”(01/01/1970)以來經過的秒數,自“紀元”以來的毫秒數time" 是一個很大的數字,不適合 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 這是必要的,因為它們是float ,並且在沒有強制轉換的情況下對它們進行的操作會導致函數返回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));
}

正如其他人所說,您可以使用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);
}

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

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

輸出:

2016-11-19 15:12:34.346351

字符串變體的最短版本(32 位兼容):

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

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

嘗試這個:

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

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 
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

注意:由於 microtime() 的改進,此函數需要 PHP5,並且還需要 bc 數學模塊(因為我們正在處理大量數字,您可以檢查 phpinfo 中是否有該模塊)。

希望這對您有所幫助。

$the_date_time = new DateTime($date_string);
$the_date_time_in_ms = ($the_date_time->format('U') * 1000) +
    ($the_date_time->format('u') / 1000);

如果您想查看真正的微秒,您需要將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);
    }

我個人使用這個:

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

這是我的實現,也應該在 32 位上工作。

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

用這個:

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

再見

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM