Bagaimana cara mendapatkan waktu saat ini dalam milidetik dalam PHP?


Jawaban:


506

The Jawaban singkatnya adalah:

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

26
@FredrikWendt, saya pikir Anda bingung time(). microtime(true)di sisi lain mengembalikan waktu saat ini dalam detik sejak zaman Unix akurat ke mikrodetik terdekat (lihat referensi PHP). Sebenarnya sangat mudah untuk menguji jika Anda menjalankan kode di atas dalam satu lingkaran dan menampilkan milidetik.
laurent

6
Saya benar-benar melakukannya! :-)
Fredrik Wendt

10
Saya suka jawaban singkatnya.
Erick Robertson

9
Bukankah seharusnya microtime(true) / 1000(pembagian bukan mulitplication)?
Jordan Lev

18
@JordanLev, seharusnya perkalian karena microtime (true) mengembalikan timestamp Unix dalam hitungan detik sebagai pelampung.
laurent

88

Gunakan microtime. Fungsi ini mengembalikan string yang dipisahkan oleh spasi. Bagian pertama adalah bagian pecahan detik, bagian kedua adalah bagian integral. Lulus trueuntuk mendapat nomor:

var_dump(microtime());       // string(21) "0.89115400 1283846202"
var_dump(microtime(true));   // float(1283846202.89)

Waspadalah terhadap kehilangan presisi jika Anda menggunakannya microtime(true).

Ada juga gettimeofdayyang mengembalikan bagian mikrodetik sebagai bilangan bulat.

var_dump(gettimeofday());
/*
array(4) {
  ["sec"]=>
  int(1283846202)
  ["usec"]=>
  int(891199)
  ["minuteswest"]=>
  int(-60)
  ["dsttime"]=>
  int(1)
}
*/

Jadi secara umum microtime()sama dengan 1000*time(), kan?
COMer

Saya melihat, mungkin ada kesalahan, tapi kesalahannya harus kurang dari itu 1000, kan?
COMer

@ COMer: Varian apa yang Anda bicarakan?
kennytm

microtime(true)dan1000*time()
COMer

@ COMer: 1000*time()tidak akan memberi Anda milidetik. microtime(true)mengembalikan floatyang memiliki 14 digit presisi. Bagian detik sudah mengambil 10, sehingga tersisa 4 digit untuk bagian mikrodetik. Ini harus cukup karena milidetik hanya membutuhkan 3 digit tambahan.
kennytm

46

Jawaban singkat:

Platform 64 bit saja!

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

[ Jika Anda menjalankan PHP 64 bit maka konstanta PHP_INT_SIZEsama dengan8 ]


Jawaban panjang:

Jika Anda ingin fungsi kesetimbangan time()dalam milidetik pertama, Anda harus mempertimbangkan bahwa sebagai time()mengembalikan jumlah detik yang berlalu sejak "zaman" (01/01/1970), jumlah milidetik sejak "zaman" adalah angka besar dan tidak masuk ke dalam integer 32 bit.

Ukuran integer di PHP bisa 32 atau 64 bit tergantung platform.

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

Ukuran integer bergantung pada platform, meskipun nilai maksimum sekitar dua miliar adalah nilai biasa (yang 32 bit ditandatangani). Platform 64-bit biasanya memiliki nilai maksimum sekitar 9E18, kecuali untuk Windows, yang selalu 32 bit. PHP tidak mendukung bilangan bulat yang tidak ditandatangani. Ukuran integer dapat ditentukan menggunakan PHP_INT_SIZE konstan, dan nilai maksimum menggunakan PHP_INT_MAX konstan sejak PHP 4.4.0 dan PHP 5.0.5.

Jika Anda memiliki bilangan bulat 64 bit maka Anda dapat menggunakan fungsi berikut:

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

microtime() mengembalikan jumlah detik sejak "zaman" dengan presisi hingga mikrodetik dengan dua angka yang dipisahkan oleh ruang, seperti ...

0.90441300 1409263371

Angka kedua adalah detik (bilangan bulat) sedangkan yang pertama adalah bagian desimal.

Fungsi di atas milliseconds()mengambil bagian integer dikalikan dengan1000

1409263371000

kemudian menambahkan bagian desimal dikalikan 1000dan dibulatkan menjadi 0 desimal

1409263371904

Perhatikan bahwa keduanya $mt[1]dan hasil rounddilemparkan ke int. Ini perlu karena mereka floats dan operasi pada mereka tanpa casting akan menghasilkan fungsi mengembalikan a float.

Akhirnya, fungsi itu sedikit lebih tepat daripada

round(microtime(true)*1000);

bahwa dengan rasio 1:10 (perkiraan) mengembalikan 1 milidetik lebih dari hasil yang benar. Hal ini disebabkan oleh ketepatan terbatas dari tipe float ( microtime(true)mengembalikan float). Pokoknya jika Anda masih lebih suka yang lebih pendek round(microtime(true)*1000);saya sarankan casting untuk inthasilnya.


Bahkan jika itu di luar ruang lingkup pertanyaan, perlu disebutkan bahwa jika platform Anda mendukung bilangan bulat 64 bit maka Anda juga bisa mendapatkan waktu saat ini dalam mikrodetik tanpa menimbulkan luapan.

Jika fakta 2^63 - 1(integer bertanda tangan terbesar) dibagi dengan 10^6 * 3600 * 24 * 365(kira-kira mikrodetik dalam satu tahun) berikan 292471.

Nilai yang sama dengan yang Anda dapatkan

echo (int)( PHP_INT_MAX / ( 1000000 * 3600 * 24 * 365 ) );

Dengan kata lain, integer 64 bit yang ditandatangani memiliki ruang untuk menyimpan rentang waktu lebih dari 200.000 tahun yang diukur dalam mikrodetik.

Anda mungkin memilikinya

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

mengapa tidak hanya: `function getMilliEpoch () {$ mt = explode ('', microtime ()); mengembalikan $ mt [1]. substr ($ mt [0], 0, 5) * 1000; ``
Michael

Sekarang ada parameter untuk fungsi microtime, jika disetel ke true, ini mengembalikan detik dan milidetik sejak 1 Januari di tahun 1970, 0 jam 0 menit 0 detik sebagai float. Berikut ini sebuah contoh: microtime (true) // 1553260455.7242
kukko

@ kukko ya, tetapi karena ketepatan terbatas dari tipe float, menghitung jumlah milicesonds dari microtime (true) akan menghasilkan nilai yang sedikit tidak akurat
Paolo

42

Seperti yang telah dinyatakan, Anda dapat menggunakan microtime()untuk mendapatkan ketepatan milidetik pada cap waktu.

Dari komentar Anda, Anda sepertinya menginginkannya sebagai Timestamp UNIX presisi tinggi. Sesuatu seperti DateTime.Now.Ticksdi dunia .NET.

Anda dapat menggunakan fungsi berikut untuk melakukannya:

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

Itulah cara melakukannya!
tonix

1
perrrrrrfect .. ♥.
BPRS dilarang

Bukankah ini mengembalikan waktu server? Dalam kasus saya, saya melihat waktu yang disimpan dalam db adalah waktu browser lokal saya. Misalkan, zona waktu memutuskan saya adalah EST + 3 dan waktu browser saya adalah GMT + 6, Sementara saya mengirimkan formulir dari lokasi GMT + 6, saya melihat waktu yang disimpan adalah GMT + 6 kali setara dengan milidetik. Jadi apa masalahnya? :(
Zenith

12

Gunakan microtime(true)di PHP 5, atau modifikasi berikut di PHP 4:

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

Cara portabel untuk menulis kode itu adalah:

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'];

keluaran:

2016-11-19 15:12:34.346351


1
Ini menggunakan stempel waktu yang sama:$t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec'];
Savvas Radevic

mikrodetik harus diisi nol:$timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);
mabi

7

coba ini:

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

Ini berfungsi bahkan jika Anda menggunakan PHP 32-bit:

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

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

Catatan ini tidak memberi Anda bilangan bulat, tetapi string. Namun ini berfungsi dengan baik dalam banyak kasus, misalnya ketika membangun URL untuk permintaan REST.


Jika Anda membutuhkan bilangan bulat, PHP 64-bit wajib diisi.

Kemudian Anda dapat menggunakan kembali kode di atas dan melemparkan ke (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

Atau Anda dapat menggunakan one-liners ol yang baik:

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

CATATAN: PHP5 diperlukan untuk fungsi ini karena perbaikan dengan microtime () dan modul matematika bc juga diperlukan (karena kita sedang berhadapan dengan angka besar, Anda dapat memeriksa apakah Anda memiliki modul di phpinfo).

Semoga ini bisa membantu Anda.


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

Apakah itu benar-benar seperti memasukkan tiga nol ke kanan?
Zeeshan

Tidak semuanya. Itu mengkonversi kedua bagian menjadi milidetik dan memberikan jumlahnya. Jadi lebih akurat daripada menambahkan nol.
user3767296

1
Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda. Tolong juga cobalah untuk tidak membuat kerumunan kode Anda dengan komentar penjelasan, ini mengurangi keterbacaan kode dan penjelasan!
Michał Perłakowski


-2

Gunakan ini:

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

Sampai jumpa

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.