Как узнать текущее время в миллисекундах в PHP?


Ответы:


506

Короткий ответ является:

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

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

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

10
Мне нравится короткий ответ.
Эрик Робертсон

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(), верно?
Прибытие

Я вижу, могут быть ошибки, но ошибка должна быть меньше 1000, верно?
Прибытие

@COMer: о каком варианте вы говорите?
Kennytm

microtime(true)и1000*time()
Прибытие

@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()в миллисекундах, вы должны учитывать, что as 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

затем добавляет десятичную часть, умноженную на 0 1000и округленную до 0

1409263371904

Обратите внимание, что оба $mt[1]и результат roundприведены к int. Это необходимо, потому что они floats и операция с ними без приведения приведет к тому, что функция вернет a 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, он возвращает секунды и миллисекунды с 1 января 1970 года, 0 час 0 минут 0 секунд в виде числа с плавающей запятой. Вот пример: microtime (true) // 1553260455.7242
kukko

@kukko да, но из-за ограниченной точности типа с плавающей точкой вычисление количества миллисекунд от микротайма (true) приведет к немного неточному значению
Paolo

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 запрещает

Разве это не вернет серверное время? В моем случае я вижу, что сохраненное время в БД - это время моего локального браузера. Предположим, мой часовой пояс 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"); 
}

7

Это работает, даже если вы используете 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 необходим для этой функции из-за улучшений с microtime (), а также необходим математический модуль 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);

Это на самом деле как заполнение трех нулей вправо?
Зеешан

Не за что. Он преобразует обе части в миллисекунды и дает сумму. Так что это точнее, чем добавлять нули.
user3767296

1
Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код. Также постарайтесь не переполнять ваш код пояснительными комментариями, это снижает удобочитаемость кода и пояснений!
Михал Перлаковский


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