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

Ответы:

506

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

$milliseconds = round(microtime(true) * 1000);
Laurent
источник
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)
}
*/
kennytm
источник
Так что, вообще говоря, 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));
}
Paolo
источник
почему бы просто: `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

mojmir.novak
источник
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"); 
}
Hồ Lê Thiện Thành
источник
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).

Надеюсь, это поможет вам.

amnippon
источник
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
источник
Это на самом деле как заполнение трех нулей вправо?
Зеешан
Не за что. Он преобразует обе части в миллисекунды и дает сумму. Так что это точнее, чем добавлять нули.
user3767296
1
Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код. Также постарайтесь не переполнять ваш код пояснительными комментариями, это снижает удобочитаемость кода и пояснений!
Михал Перлаковский
1

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 
Sadee
источник
1
В php <7.1 новые микросекунды DateTime () всегда равны 0, см. Php.net/manual/en/migration71.incompatible.php .
Маби
-2

Использовать это:

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

до свидания

MIKEEEEE
источник