รับรูปแบบวันที่ mdY H: i: su จากมิลลิวินาที


117

ฉันกำลังพยายามหาวันที่ที่จัดรูปแบบรวมถึงไมโครวินาทีจากมิลลิวินาที

ปัญหาเดียวคือฉันได้รับ 000000 เรื่อย ๆ

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

อดีต 07-28-2013 11: 26: 14.000000


6
เป็นเรื่องแปลกที่คำถามถามถึงการแปลงมิลลิวินาทีแต่ทุกคนตอบว่าจะแปลงไมโครวินาทีอย่างไร ฉันรู้ว่าคุณสามารถแปลงระหว่างทั้งสองอย่างได้ แต่ตอบคำถามจริงๆแทนที่จะคัดลอกและวางโค้ดที่ไม่เกี่ยวข้องจากเอกสาร PHP หรือที่อื่น ๆ ก็น่าจะดี
laurent

ฉันรู้ว่ามันเป็นเวลานานแล้ว แต่คำตอบของ bamosszaนั้นดีที่สุดที่ฉันพบที่นี่
Piyin

คำตอบ:


122

php.netพูดว่า:

ไมโครวินาที (เพิ่มใน PHP 5.2.2) โปรดทราบว่าdate()จะสร้างเสมอ000000เนื่องจากต้องใช้พารามิเตอร์จำนวนเต็มในขณะที่DateTime::format()รองรับไมโครวินาทีหากDateTimeสร้างด้วยไมโครวินาที

ดังนั้นใช้ง่ายๆ:

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

แนะนำและใช้dateTime()คลาสจากการอ้างอิง:

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

หมายเหตุuคือไมโครวินาที (1 วินาที = 1000000 µs)

อีกตัวอย่างจากphp.net :

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

ข้อมูลอ้างอิงของdateTime()บนphp.net

ฉันตอบคำถามสั้นและง่ายต่อผู้เขียน โปรดดูข้อมูลเพิ่มเติมสำหรับผู้เขียน: การรับรูปแบบวันที่ mdY H: i: su จากมิลลิวินาที


4
โดยทั่วไปฉันเลือกใช้รูปแบบที่สองเนื่องจากอ่านและเข้าใจได้ง่ายกว่า นอกจากนี้ DateTime ยังมีความยืดหยุ่นและแข็งแกร่งกว่าฟังก์ชันวันที่ / เวลา การจัดการไมโครวินาทีเป็นแบบ case-in-point
Herbert

3
@Geo และ AlBundy เป็นไปได้ไหมที่คุณกำลังลองใช้กับเครื่องที่มี php <5.2.2? PHP 5.4.39 ทำงานได้ดีอย่างสมบูรณ์แบบ ...
RichardBernards

มันจะไม่ง่ายเหรอ? วันที่ ('mdY H: i: s'). (int) microtime (จริง);
อนันต์

@ แอนต์มันจะค่อนข้างง่ายแน่นอน แต่ผิด. ;) สิ่งที่คุณได้รับมีเพียงแค่ยุคในไม่กี่วินาที (น่าเสียดายที่ใช้ไม่ได้microtime(false)เช่นกัน)
Sz

รหัสนี้ใช้ไม่ได้กับทุกภาษาอย่างถูกต้อง บางประเทศเช่นเยอรมนีเขียน "0,1234" หรือ "0.1234" แทน ".1234" ดังนั้นรหัสของคุณจึงให้ผลลัพธ์ต่อไปนี้สำหรับฉัน: 2012-07-08 11:14:15.0.889342
Daniel Marschall

138

U.uคุณพร้อมที่จะทำเช่นนี้นี้มีรูปแบบการป้อนข้อมูล

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

สิ่งนี้สร้างผลลัพธ์ต่อไปนี้:

04-13-2015 05:56:22.082300

จากหน้าคู่มือ PHP สำหรับรูปแบบวันที่:

  • U = วินาทีตั้งแต่ Unix Epoch
  • u = หนึ่งในล้านของวินาที

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


ขอบคุณ giggsey ที่ชี้ให้เห็นข้อบกพร่องในคำตอบเดิมของฉันการเพิ่มnumber_format()ในบรรทัดควรแก้ไขกรณีของวินาทีที่แน่นอน เสียดายที่รู้สึกไม่ค่อยโอ่อ่าอีกต่อไป ...

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

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


หมายเหตุเกี่ยวกับเขตเวลาเพื่อตอบสนอง DaVe

โดยปกติcreateFromFormat()เมธอดจะใช้เขตเวลาท้องถิ่นหากไม่ได้ระบุไว้

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

อย่างไรก็ตามเทคนิคที่อธิบายในที่นี้คือการเริ่มต้นอ็อบเจ็กต์ DateTime โดยใช้microtime()ซึ่งจะคืนค่าจำนวนวินาทีที่ผ่านไปนับตั้งแต่ Unix Epoch (01 ม.ค. 1970 00:00:00 GMT)

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

ซึ่งหมายความว่าอ็อบเจ็กต์ DateTime ถูกเริ่มต้นโดยปริยายเป็น UTC ซึ่งใช้ได้ดีสำหรับงานภายในเซิร์ฟเวอร์ที่ต้องการติดตามเวลาที่ผ่านไป

หากคุณต้องการแสดงเวลาสำหรับเขตเวลาเฉพาะคุณต้องตั้งค่าตามนั้น อย่างไรก็ตามควรทำเป็นขั้นตอนแยกต่างหากหลังจากการเริ่มต้น ( ไม่ใช้พารามิเตอร์ที่สามของcreateFromFormat()) เนื่องจากเหตุผลที่กล่าวไว้ข้างต้น

setTimeZone()วิธีสามารถนำมาใช้เพื่อให้บรรลุความต้องการนี้

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

ตัวอย่างเช่น:

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

สร้างผลลัพธ์ต่อไปนี้:

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

โปรดทราบว่าหากคุณต้องการป้อนข้อมูลลงใน mysql รูปแบบเวลาจะต้องเป็น:

format("Y-m-d H:i:s.u")

19
หมายเหตุ: DateTime::createFromFormat('U.u', microtime(true));จะส่งคืนเท็จหากmicrotime(true)ทำงานในวินาทีที่แน่นอน มันจะส่งคืน '1438616239' แทน '1438616239.000000'
giggsey

1
ทางออกที่ดีขอบคุณ ดูเหมือนว่าฉันจะเสียเวลาท้องถิ่นในการสร้าง $ ตอนนี้จาก microtime ความคิดใด ๆ ?
daVe

1
@daVe ฉันได้เพิ่มข้อมูลเกี่ยวกับเขตเวลาแล้วฉันหวังว่านั่นคือสิ่งที่คุณเป็น
ArchCodeMonkey

1
number_formatจำเป็นเสมอแม้เมื่อมันไม่ได้อยู่ในที่สองแน่นอน มิฉะนั้นคุณจะต้องใช้precisionตัวเลือกการกำหนดค่า PHP (สำหรับ "การแสดงผล") ซึ่งไม่สูงพอโดยค่าเริ่มต้นเนื่องจาก PHP 7.0 ทำให้สูญเสียความแม่นยำ (ไม่แม่นยำถึงไมโครวินาที)
เตียวฮันฮุย

1
เลื่อนลงใน StackOverflow เสมอ
tom10271

15

นี่เป็นแนวทางที่สั้นกว่าเล็กน้อย แทนที่จะทำงานเพื่อสร้างวันที่ / เวลาที่เป็นตัวเลขที่มีความแม่นยำสูงฉันจะแปลงค่าไมโครวินาทีเป็นสตริงลบ0และเพิ่มลงในส่วนท้ายของสตริงวันที่ / เวลา ฉันสามารถตัดจำนวนทศนิยมได้อย่างง่ายดายโดยการปรับพารามิเตอร์ความยาวสตริง ที่นี่ฉันใช้4เพื่อรับมิลลิวินาที แต่คุณสามารถใช้7เพื่อรับไมโครวินาที

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

สำหรับค่า microtime () ของผลตอบแทนนี้0.98236000 140740057308-07-14 01:08:13.982



6
echo date('m-d-Y H:i:s').substr(fmod(microtime(true), 1), 1);

ตัวอย่างผลลัพธ์:

02-06-2019 16:45:03.53811192512512

หากคุณต้องการ จำกัด จำนวนตำแหน่งทศนิยมบรรทัดด้านล่าง (credit mgutt) จะเป็นทางเลือกที่ดี (ด้วยรหัสด้านล่าง 6 จะ จำกัด จำนวนตำแหน่งทศนิยมไว้ที่ 6)

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

ตัวอย่างผลลัพธ์:

02-11-2019 15:33:03.624493

คุณพลาดความแม่นยำและนำศูนย์ไปชั่ววินาที echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));ดังนั้นรุ่นที่ถูกต้องควรจะเป็น คำอธิบายว่าทำไมเราถึงต้องการ09: stackoverflow.com/a/28739819/318765
mgutt

คุณพลาดความแม่นยำอีกแล้ว;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt

แต่ระวังsubstr()อย่าปัด และใน compination กับround()มันจะตัดเลขศูนย์ต่อท้าย: stackoverflow.com/questions/7493305/... Thats sprintf()เหตุผลว่าทำไมฉันเสนอ
mgutt

@mgutt เมื่อไหร่หลักแรกจะไม่เป็นศูนย์? โดยพื้นฐานแล้วสิ่งที่จำเป็นคือเพียงแค่ลบศูนย์ที่อยู่ตรงนั้นเสมอเมื่อรับส่วนที่เหลือจาก fmod โดย 1 คำถามจะถามเป็นไมโครวินาที แต่อยู่ในรูปของตำแหน่งทศนิยมของวินาที ไม่มีเหตุผลที่จะ จำกัด จำนวนตำแหน่งทศนิยม ตำแหน่งทศนิยมที่มากขึ้นคือความแม่นยำที่ดีขึ้น
ghbarratt

@mgutt ฉันเพิ่มทางเลือกแรกที่คุณแนะนำให้กับคำตอบของฉันอธิบายว่านั่นเป็นวิธีที่ดีในการ จำกัด จำนวนตำแหน่งทศนิยมหากจำเป็น
ghbarratt

3

หากคุณต้องการจัดรูปแบบวันที่เช่น JavaScript (new Date()).toISOString()ด้วยเหตุผลบางประการนี่คือวิธีที่คุณสามารถทำได้ใน PHP:

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

ตัวอย่างผลลัพธ์:

2016-04-27T18:25:56.696Z

เพียงเพื่อพิสูจน์ว่าการลบจำนวนเต็มไม่ได้ลดความแม่นยำของส่วนทศนิยม:

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

PHP ได้รอบตำแหน่งทศนิยม แต่มันกลมพวกเขาด้วยวิธีเดียวกันในทั้งสองกรณี


1
ไม่อย่าใช้คณิตศาสตร์กับเลขทศนิยมเพราะมันไม่ถูกต้อง ยังไม่ต้องเสียเวลาเรียกใช้ฟังก์ชันต่างๆ เพียงแค่ใช้ substr () เพื่อตัดทอนวันที่ที่จัดรูปแบบให้เหลือทศนิยมสามตำแหน่ง
LS

@LS การตัดทอนจะไม่ปัดเศษทศนิยมที่ 3 ซึ่งอาจไม่ถูกต้องมากยิ่งขึ้น ลอยไม่พังจนกว่าคุณจะเข้าไปในพื้นที่เล็ก ๆ ทศนิยม 3 ตำแหน่งน่าจะใช้ได้ ที่จริงฉันไม่คิดว่าฉันจะเปลี่ยนความแม่นยำเลย แต่การลอยตัวจะแม่นยำยิ่งขึ้นยิ่งคุณเข้าใกล้ 0 มากขึ้นการลบจำนวนเต็มออกไม่ควรเปลี่ยนตำแหน่งทศนิยม AFAIK
mpen

เกี่ยวกับอะไรdate('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));?
F8ER

@ F8ER ถ้าคุณ$timeอยู่ในหน่วยมิลลิวินาทีแล้วใช่ว่าจะใช้ได้ผล ไม่ชอบsubstrแฮ็ค แต่ฉันคิดว่ามันน่าจะใช้ได้ในช่วงปี 2544 ถึง 2286
mpen

ใช่$timeMS คืออะไร แต่2286ฉันหมายความว่าทำไมคิดอย่างนั้นและจะเป็นไปได้อย่างไรที่จะหลบหนีเช่นนั้น?
F8ER

3

นี่เป็นไปตามคำตอบจาก ArchCodeMonkey

แต่ทำให้ง่ายขึ้นถ้าคุณต้องการบางสิ่งบางอย่างที่รวดเร็ว

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

สำหรับฉันแล้ว

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

3

นี่เป็นอีกวิธีหนึ่งที่ฉันพบว่าหรูหรา / เรียบง่ายกว่าเล็กน้อย:

echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));

2

ใน PHP 7.1 คุณสามารถทำได้:

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

จะแสดงเป็น:

04-11-2018 10:54:01.321688

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;

0

เอกสารระบุว่าต่อไปนี้:

ไมโครวินาที (เพิ่มใน PHP 5.2.2) โปรดทราบว่า date () จะสร้าง 000000 เสมอเนื่องจากใช้พารามิเตอร์จำนวนเต็มในขณะที่ DateTime :: format () รองรับ microseconds

เช่นใช้ DateTime แทน


6
ไม่ได้ผล! date_format (DateTime ใหม่ (), 'u') ให้ค่าศูนย์: phpfiddle.org/lite/code/ggh-mvz
Jānis Elmeris

ใช่ตามคำตอบด้านบน (และการทดลองของฉัน) new DateTime()จะคืนค่า 0000 ให้คุณด้วย แต่ถ้าคุณระบุเวลาที่มีความแม่นยำระดับไมโครวินาทีเมื่อสร้างอินสแตนซ์มันก็ใช้ได้
scipilot

@scipilot ตกลงแล้วคุณจะทำอย่างไร?
Geo

@Geo ดูคำตอบที่ยอมรับ new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot

0

ด้วย PHP 7.0+ ตอนนี้คุณสามารถทำสิ่งต่อไปนี้:

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

สิ่งนี้ทำสิ่งต่อไปนี้ตามลำดับ:

  1. ตัดค่าศูนย์ 4 ตัวสุดท้ายออกจากสตริงเพื่อDate()จัดการกับวันที่
  2. ใช้วันที่เพื่อจัดรูปแบบมิลลิวินาทีเป็นสตริงเวลาวันที่ที่ DateTime เข้าใจได้
  3. DateTime()จากนั้นจะอนุญาตให้คุณแก้ไขเขตเวลาที่คุณอยู่ได้ แต่ต้องแน่ใจว่าdate_default_timezone_set("Timezone");ได้ตั้งค่าก่อนที่คุณจะใช้DateTime()ฟังก์ชันและคลาส
  4. เป็นแนวทางปฏิบัติที่ดีในการใช้ตัวสร้างในชั้นเรียนของคุณเพื่อให้แน่ใจว่าคุณอยู่ในเขตเวลาที่ถูกต้องเมื่อใช้DateTime()คลาสหรือฟังก์ชัน

0

หากคุณใช้ Carbon คุณสามารถใช้ข้อมูลจำเพาะที่กำหนดไว้ "RFC3339_EXTENDED" หรือปรับแต่ง

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

0

ขึ้นอยู่กับคำตอบของ @ArchCodeMonkey

หากคุณมีdeclare(strict_types=1)คุณต้องส่งอาร์กิวเมนต์ที่สองเป็นสตริง

ใส่คำอธิบายภาพที่นี่


0

ฉันนั่งรถสองสามวิธี:

1) microtime + sscanf + วันที่:

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

ฉันไม่แน่ใจว่าทำไม microtime () คืนค่า 10 ตัวอักษร (0.dddddd00) สำหรับส่วนไมโครวินาที แต่อาจมีคนบอกฉันได้

$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) DateTime :: createFromFormat + Datetime-> รูปแบบ:

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

ไม่ทำงานใน 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 + วันที่:

$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-> รูปแบบ:

$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-> รูปแบบ:

$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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.