tl; dr. Gunakan microtime(false) dan simpan hasilnya di MySQL bigint sebagai sepersejuta detik. Jika tidak, Anda harus mempelajari semua tentang aritmatika floating point, yang merupakan bola rambut besar yang gemuk.
Fungsi waktu mikro PHP mengambil stempel waktu Unix (saat ini sekitar hex 50eb7c00 atau desimal 1.357.609.984) dari satu panggilan sistem, dan waktu mikrodetik dari panggilan sistem lain. Itu kemudian membuat mereka menjadi string karakter. Kemudian, jika Anda memanggilnya dengan (benar) itu mengubah nomor itu menjadi nomor floating point IEEE 745 64-bit, sesuatu yang PHP sebut sebagai float
.
Mulai hari ini Anda memerlukan sepuluh digit desimal di sebelah kiri titik desimal untuk menyimpan stempel waktu UNIX bilangan bulat. Itu akan tetap benar sampai sekitar 2280 CE ketika keturunan Anda akan mulai membutuhkan sebelas digit. Anda memerlukan enam digit di sebelah kanan tempat desimal untuk menyimpan mikrodetik.
Anda tidak akan mendapatkan akurasi mikrodetik total. Sebagian besar sistem mempertahankan jam sistem sub-detik mereka dengan resolusi sekitar 1-33 milidetik. Ini bergantung pada sistem.
MySQL versi 5.6.4 dan yang lebih baru memungkinkan Anda untuk menentukan DATETIME(6)
kolom, yang akan menyimpan tanggal dan waktu ke resolusi mikrodetik. Jika Anda menggunakan versi MySQL seperti itu, itulah cara yang tepat.
Sebelum versi 5.6.4, Anda harus menggunakan DOUBLE
MySQL (IEEE 754 64-bit floating point) untuk menyimpan angka-angka ini. MySQL FLOAT
(IEEE 754 32-bit floating point) tidak memiliki cukup bit dalam mantissanya untuk menyimpan bahkan waktu UNIX saat ini dalam hitungan detik secara akurat.
Mengapa Anda menyimpan stempel waktu ini? Apakah Anda berharap untuk melakukan
WHERE table.timestamp = 1357609984.100000
atau pertanyaan serupa untuk mencari item tertentu? Itu penuh dengan bahaya jika Anda menggunakan angka float atau double di mana saja dalam rantai pemrosesan Anda (yaitu, bahkan jika Anda menggunakan microtime(true)
bahkan sekali). Mereka terkenal karena tidak tampil setara bahkan ketika Anda pikir mereka harus melakukannya. Sebaliknya Anda perlu menggunakan sesuatu seperti ini. 0.001
Ini disebut "epsilon" dalam perdagangan pemrosesan numerik.
WHERE table.timestamp BETWEEN 1357609984.100000 - 0.001
AND 1357609984.100000 + 0.001
atau sesuatu yang serupa. Anda tidak akan mengalami masalah ini jika menyimpan stempel waktu ini sebagai desimal atau dalam sepersejuta detik dalam bigint
kolom.
IEEE 64-bit floating point memiliki 53 bit mantissa -- presisi. Stempel waktu UNIX Epoch saat ini (detik sejak 1-Jan-1970 00:00Z) kali satu juta menggunakan 51 bit. Jadi tidak banyak presisi ekstra dalam DOUBLE jika kita peduli dengan bit orde rendah. Di sisi lain, presisi tidak akan habis selama beberapa abad.
Anda hampir kehabisan presisi dengan int64(BIGINT). Jika saya benar-benar menyimpan stempel waktu mikrodetik hanya untuk memesannya di MySQL, saya akan menggunakan DATETIME(6)
karena saya akan mendapatkan banyak aritmatika tanggal secara gratis. Jika saya melakukan aplikasi volume tinggi dalam memori, saya akan menggunakan int64.