Як отримати поточний час в мілісекундах в PHP?


Відповіді:


506

Коротка відповідь є:

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

26
@FredrikWendt, я думаю, ви з цим плутаєтесь time(). microtime(true)з іншого боку, повертає поточний час у секундах з точної епохи Unix до найближчої мікросекунди (див. посилання PHP). Це насправді дуже просто перевірити, якщо запустити вищевказаний код у циклі і відобразити мілісекунди.
Лоран

6
Я абсолютно зробив! :-)
Фредрік Вендт

9
Мені подобається коротка відповідь.
Ерік Робертсон

9
Чи не повинно це бути microtime(true) / 1000(поділ замість мультиплікації)?
Йордан Лев

18
@JordanLev, це повинно бути множення, тому що microtime (true) повертає часову позначку Unix за секунди у вигляді поплавця.
Лоран

88

Використовуйте 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(), правда?
COMER

Я бачу, помилки можуть бути, але помилка повинна бути менше 1000, правда?
COMER

@COMer: Про який варіант ти йдеш?
kennytm

microtime(true)і1000*time()
COMER

@COMer: 1000*time()не дасть вам мілісекунд. microtime(true)повертає a, floatщо має 14 цифр точності. На секунду частина вже зайняла 10, так що залишилося 4 цифри для мікросекундної частини. Цього має бути достатньо, оскільки для мілісекунд потрібні лише 3 додаткові цифри.
kennytm

46

Коротка відповідь:

Тільки 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), кількість мілісекунд з моменту "часу епохи" є великим числом і не вписується в ціле число 32 біт.

Розмір цілого числа в PHP може становити 32 або 64 біта залежно від платформи.

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

Розмір цілого числа залежить від платформи, хоча максимальне значення близько двох мільярдів - це звичайне значення (це 32 біти підписано). 64-бітні платформи зазвичай мають максимальне значення близько 9E18, за винятком Windows, яка завжди 32-бітна. PHP не підтримує непідписані цілі числа. Розмір цілого числа може бути визначений за допомогою постійної PHP_INT_SIZE, а максимальне значення, використовуючи постійну PHP_INT_MAX з PHP 4.4.0 та PHP 5.0.5.

Якщо у вас 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, і робота над ними без викидання призведе до повернення функції afloat .

Нарешті, ця функція дещо точніша, ніж

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

чому б не просто: `функція getMilliEpoch () {$ mt = explode ('', microtime ()); повернути $ mt [1]. substr ($ mt [0], 0, 5) * 1000; } `
Михайло

Тепер є параметр для функції мікрочасу, якщо його встановлено на істинне, воно повертає секунди і мілісекунди з 1 січня 1970 року, 0 години 0 хвилин 0 секунд як плаваюче. Ось приклад: microtime (true) // 1553260455.7242
kukko

@kukko так, але через обмежену точність типу поплавця обчислення кількості мільйонних секунд від мікрочасу (вірно) призведе до дещо неточного значення
Паоло

42

Як вже було зазначено в іншому, ви можете використовувати microtime()для отримання точності мілісекунд на часових позначках.

З ваших коментарів вам здається, що ви хочете це як високоточну часову марку UNIX. Щось на зразок DateTime.Now.Ticksсвіту .NET.

Для цього ви можете використовувати таку функцію:

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

Ось так це зробити!
tonix

1
perrrrrrfect .. ♥.
SRB забороняє

Чи не повертається час сервера? У моєму випадку я бачу, що збережений час у db - це час локального браузера. Припустимо, мій часовий пояс є EST + 3, а час мого веб-переглядача - GMT + 6. Хоча я надсилаю форму з місця розташування GMT + 6, я бачу, що збережений час є GMT + 6 еквівалентним часом мілісекунди. Отже, в чому проблема? :(
Зеніт

12

Використання microtime(true)в PHP 5 або наступна модифікація в PHP 4:

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

Портативним способом написання цього коду було б:

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

    return microtime(true);
}

11

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

вихід:

2016-11-19 15:12:34.346351


1
Тут використовується та сама мітка часу:$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

спробуйте це:

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

6

Це працює, навіть якщо ви перебуваєте на 32-розрядному PHP:

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

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

Зауважте, це дає не цілі числа, а рядки. Однак це прекрасно спрацьовує у багатьох випадках, наприклад, при створенні URL-адрес для REST-запитів.


Якщо вам потрібні цілі числа, 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

5
$timeparts = explode(" ",microtime());
$currenttime = bcadd(($timeparts[0]*1000),bcmul($timeparts[1],1000));
echo $currenttime;

ПРИМІТКА. Для цієї функції потрібен PHP5 завдяки покращенню мікрочасу (), а також потрібен модуль математики bc (оскільки ми маємо справу з великою кількістю, ви можете перевірити, чи є у вас модуль у phpinfo).

Сподіваюся, це допоможе тобі.


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

Це насправді як прокладка трьох нулів праворуч?
Зеешан

Зовсім ні. Він перетворює обидві частини в мілісекунди і дає суму. Тож точніше, ніж додавати нулі.
користувач3767296

1
Хоча цей фрагмент коду може вирішити питання, у тому числі пояснення дійсно допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду. Будь ласка, намагайтеся не переповнювати свій код пояснювальними коментарями, це зменшує читабельність і коду, і пояснень!
Michał Perłakowski


-2

Використовуй це:

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

До побачення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.