mendapatkan format tanggal mdY H: i: su dari milidetik

117

Saya mencoba mendapatkan tanggal yang diformat, termasuk mikrodetik dari milidetik.

Satu-satunya masalah adalah saya terus mendapatkan 000000

date("m-d-Y H:i:s.u", $milliseconds/1000);

ex. 07-28-2013 11: 26: 14.000000

slik
sumber
6
Aneh bahwa pertanyaan tersebut meminta konversi milidetik , tetapi semua orang menjawab cara mengonversi mikrodetik. Saya tahu Anda dapat mengonversi di antara keduanya tetapi benar-benar menjawab pertanyaan alih-alih menyalin dan menempelkan kode yang tidak terkait dari dokumen PHP atau di tempat lain akan menyenangkan.
laurent
Saya tahu sudah lama, tetapi jawaban bamossza adalah yang terbaik yang saya temukan di sini
Piyin

Jawaban:

122

php.net mengatakan:

Microseconds (ditambahkan dalam PHP 5.2.2). Perhatikan bahwa itu date()akan selalu menghasilkan 000000karena dibutuhkan parameter integer, sedangkan DateTime::format()mendukung mikrodetik jika DateTimedibuat dengan mikrodetik.

Jadi gunakan sesederhana itu:

$micro_date = microtime();
$date_array = explode(" ",$micro_date);
$date = date("Y-m-d H:i:s",$date_array[1]);
echo "Date: $date:" . $date_array[0]."<br>";

Direkomendasikan dan gunakan dateTime()kelas dari referensi:

$t = microtime(true);
$micro = sprintf("%06d",($t - floor($t)) * 1000000);
$d = new DateTime( date('Y-m-d H:i:s.'.$micro, $t) );

print $d->format("Y-m-d H:i:s.u"); // note at point on "u"

Catatan uadalah mikrodetik (1 detik = 1000000 µs).

Contoh lain dari php.net :

$d2=new DateTime("2012-07-08 11:14:15.889342");

Referensi dateTime()di php.net

Saya telah menjawab pertanyaan secara singkat dan mempermudah penulis. Silakan lihat untuk informasi lebih lanjut kepada penulis: mendapatkan format tanggal mdY H: i: su dari milidetik

Marin Sagovac
sumber
4
Saya biasanya memilih bentuk kedua karena lebih mudah dibaca dan dipahami. Selain itu, DateTime jauh lebih fleksibel dan kuat daripada fungsi tanggal / waktu. Menangani mikrodetik adalah kasus yang tepat.
Herbert
3
@ Geo dan AlBundy mungkinkah Anda mencoba ini pada mesin dengan php <5.2.2? PHP 5.4.39 berjalan dengan baik ...
RichardBernards
bukankah ini mudah? tanggal ('mdY H: i: s'). (int) waktu mikro (benar);
Anant
@Anant, itu akan sangat mudah, memang. Tapi salah. ;) Apa yang Anda dapatkan di sana hanya dalam hitungan detik. (Sayangnya, tidak akan berhasil microtime(false).)
Sz.
Kode ini tidak bekerja di semua lokal dengan benar. Beberapa negara seperti Jerman menulis "0,1234" atau "0.1234" bukan ".1234", oleh karena itu kode Anda memberikan keluaran berikut untuk saya: 2012-07-08 11:14:15.0.889342
Daniel Marschall
138

Anda dapat dengan mudah melakukan ini dengan format input U.u.

$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");

Ini menghasilkan keluaran berikut:

04-13-2015 05:56:22.082300

Dari halaman manual PHP untuk format tanggal:

  • U = Detik sejak Unix Epoch
  • u = Mikrodetik

http://php.net/manual/en/function.date.php


Terima kasih untuk cekikikan karena menunjukkan cacat dalam jawaban asli saya, menambahkan number_format()baris harus memperbaiki kasus detik yang tepat. Sayang sekali rasanya tidak seanggun lagi ...

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));

http://php.net/manual/en/function.number-format.php


Catatan tentang zona waktu sebagai tanggapan atas DaVe.

Biasanya createFromFormat()metode ini akan menggunakan zona waktu lokal jika tidak ditentukan.

http://php.net/manual/en/datetime.createfromformat.php

Namun, teknik yang dijelaskan di sini adalah menginisialisasi objek DateTime microtime()yang mengembalikan jumlah detik yang telah berlalu sejak Unix Epoch (01 Jan 1970 00:00:00 GMT).

http://php.net/manual/en/function.microtime.php

Ini berarti bahwa objek DateTime secara implisit diinisialisasi ke UTC, yang baik untuk tugas internal server yang hanya ingin melacak waktu yang telah berlalu.

Jika Anda perlu menampilkan waktu untuk zona waktu tertentu, maka Anda perlu mengaturnya. Namun, ini harus dilakukan sebagai langkah terpisah setelah inisialisasi ( tidak menggunakan parameter ketiga createFromFormat()) karena alasan yang dibahas di atas.

The setTimeZone()metode dapat digunakan untuk mencapai persyaratan ini.

http://php.net/manual/en/datetime.settimezone.php

Sebagai contoh:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
echo $now->format("m-d-Y H:i:s.u") . '<br>';

$local = $now->setTimeZone(new DateTimeZone('Australia/Canberra'));
echo $local->format("m-d-Y H:i:s.u") . '<br>';

Menghasilkan keluaran sebagai berikut:

10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818

Perhatikan bahwa jika Anda ingin memasukkan mysql, format waktu harus:

format("Y-m-d H:i:s.u")
ArchCodeMonkey
sumber
19
Catatan: DateTime::createFromFormat('U.u', microtime(true));akan mengembalikan nilai salah jika microtime(true)dijalankan tepat pada detik. Ini mengembalikan '1438616239' bukan '1438616239.000000'.
giggsey
1
Solusi hebat, terima kasih. Sepertinya saya kehilangan waktu lokal saya membuat $ sekarang dari microtime. Ada ide?
daVe
1
@daVe Saya telah menambahkan beberapa informasi tentang zona waktu, saya harap itulah yang Anda cari.
ArchCodeMonkey
1
Itu number_formatselalu diperlukan, bahkan saat itu tidak tepat pada detik. Jika tidak, Anda bergantung pada precisionopsi konfigurasi PHP (untuk "tampilan"), yang tidak cukup tinggi secara default pada PHP 7.0 yang menyebabkan hilangnya presisi (tidak akurat hingga mikrodetik).
Teoh Han Hui
1
Selalu gulir ke bawah di StackOverflow
tom10271
15

Berikut pendekatan yang sedikit lebih pendek. Daripada bekerja untuk membuat tanggal / waktu numerik presisi tinggi, saya mengonversi nilai mikrodetik menjadi string, menghapus 0, dan menambahkannya ke akhir string tanggal / waktu. Saya dapat dengan mudah memangkas jumlah desimal dengan menyesuaikan parameter panjang string; di sini saya gunakan 4untuk mendapatkan milidetik, tetapi Anda bisa menggunakannya 7untuk mendapatkan mikrodetik.

$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);

Untuk nilai microtime () 0.98236000 1407400573, ini mengembalikan 08-07-14 01:08:13.982.

thotso
sumber
9

Saya menggunakan

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

output: 2017-09-05 17:04:57.555036
bamossza.dll
sumber
6
echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);

contoh keluaran:

02-06-2019 16:45:03.53811192512512

Jika Anda memiliki kebutuhan untuk membatasi jumlah tempat desimal maka baris di bawah ini (mgutt kredit) akan menjadi alternatif yang baik. (Dengan kode di bawah ini, angka 6 membatasi jumlah tempat desimal menjadi 6.)

echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));

contoh keluaran:

02-11-2019 15:33:03.624493
ghbarratt.dll
sumber
Anda melewatkan presisi dan nol di depan untuk detik. Jadi versi yang benar seharusnya echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));. Penjelasan mengapa kita membutuhkan 09: stackoverflow.com/a/28739819/318765
mgutt
Anda melewatkan presisi lagi;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt
Tapi hati-hati, substr()tidak bulat. Dan jika digabungkan dengan round()itu akan memotong angka nol yang tertinggal: stackoverflow.com/questions/7493305/… Itulah alasan mengapa saya mengusulkan sprintf().
mgutt
@mgutt Kapan digit pertama tidak menjadi nol? Pada dasarnya yang dibutuhkan hanyalah menghilangkan nol yang selalu ada ketika mendapatkan sisa dari fmod sebesar 1. Pertanyaan menanyakan mikrodetik tetapi dalam bentuk tempat desimal dari detik. Tidak ada alasan untuk membatasi jumlah tempat desimal. Lebih banyak tempat desimal berarti presisi yang lebih baik.
ghbarratt
@mgutt Saya menambahkan alternatif pertama Anda yang disarankan ke jawaban saya, menjelaskan bahwa itu akan menjadi cara yang baik untuk membatasi jumlah tempat desimal jika diperlukan
ghbarratt
3

Jika Anda ingin memformat tanggal seperti JavaScript (new Date()).toISOString()karena alasan tertentu, berikut cara melakukannya di PHP:

$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));

Output sampel:

2016-04-27T18:25:56.696Z

Hanya untuk membuktikan bahwa mengurangi bilangan bulat tidak mengurangi keakuratan bagian desimal:

>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"

PHP melakukan pembulatan tempat desimal, tetapi membulatkannya dengan cara yang sama dalam kedua kasus.

mpen
sumber
1
Tidak. Jangan gunakan matematika pada bilangan floating point, itu tidak akurat. Juga jangan buang waktu untuk memanggil beberapa fungsi. Cukup gunakan substr () untuk memotong tanggal yang diformat menjadi tiga tempat desimal.
LS
@LS Memotong tidak akan membulatkan desimal ke-3 yang mungkin bahkan lebih tidak akurat. Float tidak akan rusak sampai Anda mendapatkan presisi yang sangat kecil; 3 tempat desimal sudah cukup. Sebenarnya, saya rasa saya tidak mengubah presisi sama sekali, float menjadi lebih akurat semakin Anda mendekati 0. Mengurangkan bilangan bulat tidak akan mengubah tempat desimal AFAIK.
mpen
Tentang apa date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));?
F8ER
@ F8ER Jika Anda $timesudah dalam milidetik, ya, secara teknis itu akan berhasil. Jangan suka substrhacknya, tapi saya rasa ini akan berhasil untuk tanggal antara 2001 dan 2286.
mpen
Ya, $timeitu MS, tapi bagaimana dengan 2286, maksud saya mengapa berpikir begitu dan bagaimana mungkin untuk menghindarinya?
F8ER
3

Ini berdasarkan jawaban dari ArchCodeMonkey.

Tetapi hanya disederhanakan, jika Anda hanya menginginkan sesuatu yang cepat dan berfungsi.

function DateTime_us_utc(){
    return DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
}
function DateTime_us(){
    $now = DateTime_us_utc();
    return $now->setTimeZone(new DateTimeZone(date_default_timezone_get()));
}

Jadi bagi saya

$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");
John Kearney
sumber
3

Berikut metode lain yang menurut saya sedikit lebih elegan / sederhana:

echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));
SDpyro
sumber
1
// Procedural
$fineStamp = date('Y-m-d\TH:i:s') . substr(microtime(), 1, 9);
echo $fineStamp . PHP_EOL;

// Object-oriented (if you must). Still relies on $fineStamp though :-\
$d = new DateTime($fineStamp);
echo $d->format('Y-m-d\TH:i:s.u') . PHP_EOL;
Geo
sumber
1

Pada PHP 7.1 Anda cukup melakukan ini:

$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );

Ini akan ditampilkan sebagai:

04-11-2018 10:54:01.321688
Harveyhase68
sumber
0

Dokumentasinya mengatakan yang berikut:

Microseconds (ditambahkan dalam PHP 5.2.2). Perhatikan bahwa date () akan selalu menghasilkan 000000 karena ini mengambil parameter integer, sedangkan DateTime :: format () mendukung mikrodetik.

Yaitu, gunakan DateTime sebagai gantinya.

Havsmonstret
sumber
6
Ini tidak bekerja! date_format (DateTime baru (), 'u') memberikan nol: phpfiddle.org/lite/code/ggh-mvz
Jānis Elmeris
Ya sesuai jawaban di atas (dan percobaan saya) new DateTime()juga akan mengembalikan 0000 untuk Anda. Tetapi jika Anda memberikan waktu akurasi mikrodetik saat membuat instance, itu berfungsi dengan baik.
scipilot
@scipilot ok, jadi bagaimana Anda melakukannya?
Geo
@ Geo melihat jawaban yang diterima. new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot
0

Dengan PHP 7.0+ sekarang di sini Anda dapat melakukan hal berikut:

$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));

Ini melakukan hal berikut secara berurutan:

  1. Memangkas 4 angka nol terakhir dari string sehingga Date()dapat menangani tanggal.
  2. Menggunakan tanggal untuk memformat milidetik menjadi string waktu tanggal yang dapat dipahami DateTime.
  3. DateTime()kemudian dapat memungkinkan Anda untuk mengubah zona waktu tempat Anda berada, tetapi pastikan itu date_default_timezone_set("Timezone");disetel sebelum Anda menggunakan DateTime()fungsi dan kelas.
  4. Merupakan praktik yang baik untuk menggunakan konstruktor di kelas Anda untuk memastikan Anda berada dalam zona waktu yang benar saat DateTime()kelas atau fungsi digunakan.
Jamie Ross
sumber
0

jika Anda menggunakan Karbon, Anda dapat menggunakan spesifikasi yang ditentukan "RFC3339_EXTENDED". atau sesuaikan.

Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';
Aiden Moon
sumber
0

Berdasarkan jawaban @ArchCodeMonkey.

Jika sudah, declare(strict_types=1)Anda harus melemparkan argumen kedua ke string

masukkan deskripsi gambar di sini

SandroMarques
sumber
0

Saya mengambil beberapa cara berbeda:

1) microtime + sscanf + tanggal:

sscanf(microtime(), '0.%6s00 %s', $usec, $sec);
$date = date('Y-m-d H:i:s.', $sec) . $usec;

Saya tidak yakin mengapa microtime () mengembalikan 10 karakter (0.dddddd00) untuk bagian mikrodetik tetapi mungkin seseorang dapat memberi tahu saya?

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { sscanf(microtime(), '0.%6s00 %s', $usec, $sec); $date = date('Y-m-d H:i:s.', $sec) . $usec; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "22372.335910797 ms" // macOS PHP 5.6.30
string(18) "16772.964000702 ms" // Linux PHP 5.4.16
string(18) "10382.229089737 ms" // Linux PHP 7.3.11 (same linux box as above)

2) format DateTime :: createFromFormat + Datetime->:

$now = new DateTime('NOW');
$date = $now->format('Y-m-d H:i:s.u');

tidak berfungsi di PHP 5.x ...

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = new DateTime('NOW'); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "45801.825046539 ms" // macOS PHP 5.6.30 (ms not working)
string(18) "21180.155038834 ms" // Linux PHP 5.4.16 (ms not working)
string(18) "11879.796028137 ms" // Linux PHP 7.3.11 (same linux box as above)

3) gettimeofday + date:

$time = gettimeofday();
$date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec'];

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $time = gettimeofday(); $date = date('Y-m-d H:i:s.', $time['sec']) . $time['usec']; } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "23706.788063049 ms" // macOS PHP 5.6.30
string(18) "14984.534025192 ms" // Linux PHP 5.4.16
string(18) "7799.1390228271 ms" // Linux PHP 7.3.11 (same linux box as above)

4) microtime + number_format + DateTime :: createFromFormat + DateTime-> format:

$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', '')); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "83326.496124268 ms" // macOS PHP 5.6.30
string(18) "61982.603788376 ms" // Linux PHP 5.4.16
string(16) "19107.1870327 ms" // Linux PHP 7.3.11 (same linux box as above)

5) microtime + sprintf + DateTime :: createFromFormat + DateTime-> format:

$now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true)));
$date = $now->format('Y-m-d H:i:s.u');

-

$start_ts = microtime(true); for($i = 0; $i < 10000000; $i++) { $now = DateTime::createFromFormat('U.u', sprintf('%.6f', microtime(true))); $date = $now->format('Y-m-d H:i:s.u'); } var_dump((microtime(true) - $start_ts)*1000 . ' ms');
string(18) "79387.331962585 ms" // macOS PHP 5.6.30
string(18) "60734.437942505 ms" // Linux PHP 5.4.16
string(18) "18594.941139221 ms" // Linux PHP 7.3.11 (same linux box as above)
Fravadona
sumber