nhận định dạng ngày tháng mdY H: i: su từ mili giây


117

Tôi đang cố gắng lấy một ngày được định dạng, bao gồm cả micro giây từ mili giây.

Vấn đề duy nhất là tôi tiếp tục nhận được 000000

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

Ví dụ. 28/07/2013 11: 26: 14.000000


6
Thật kỳ lạ khi câu hỏi yêu cầu chuyển đổi mili giây , nhưng mọi người đều trả lời cách chuyển đổi micro giây. Tôi biết bạn có thể chuyển đổi giữa cả hai nhưng thực sự trả lời câu hỏi thay vì sao chép và dán mã không liên quan từ tài liệu PHP hoặc nơi khác sẽ rất tốt.
laurent

Tôi biết đã lâu rồi, nhưng câu trả lời của bamossza là câu trả lời hay nhất mà tôi tìm thấy ở đây
Piyin

Câu trả lời:


122

php.net nói:

Microseconds (được bổ sung trong PHP 5.2.2). Lưu ý rằng date()sẽ luôn tạo 000000vì nó nhận tham số số nguyên, trong khi DateTime::format()hỗ trợ micro giây nếu DateTimeđược tạo bằng micro giây.

Vì vậy, sử dụng như đơn giản:

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

Được đề xuất và sử dụng dateTime()lớp từ được tham chiếu:

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

Lưu ý ulà micro giây (1 giây = 1000000 µs).

Một ví dụ khác từ php.net :

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

Tham khảo của dateTime()trên php.net

Tôi đã trả lời câu hỏi ngắn gọn và đơn giản hóa cho tác giả. Vui lòng xem để biết thêm thông tin về tác giả: nhận định dạng ngày mdY H: i: su từ mili giây


4
Tôi thường chọn hình thức thứ hai vì nó dễ đọc và dễ hiểu hơn. Ngoài ra, DateTime linh hoạt và mạnh mẽ hơn nhiều so với các chức năng ngày / giờ. Xử lý micro giây là một trường hợp trong điểm.
Herbert

3
@Geo và AlBundy có thể là bạn đang thử điều này trên máy có php <5.2.2 không? PHP 5.4.39 chạy này hoàn toàn tốt đẹp ...
RichardBernards

điều này sẽ không dễ dàng? date ('mdY H: i: s'). (int) microtime (true);
Anant

@Anant, quả thực là khá dễ dàng. Nhưng sai lầm. ;) Những gì bạn nhận được chỉ là kỷ nguyên trong vài giây. (Thật không may, cũng không hoạt động với microtime(false).)
Sz.

Mã này không hoạt động chính xác trên tất cả các ngôn ngữ. Một số quốc gia như Đức viết "0,1234" hoặc "0,1234" thay vì ".1234", do đó mã của bạn cung cấp kết quả sau cho tôi: 2012-07-08 11:14:15.0.889342
Daniel Marschall

138

Bạn có thể dễ dàng thực hiện việc này với định dạng đầu vào U.u.

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

Điều này tạo ra kết quả sau:

04-13-2015 05:56:22.082300

Từ trang hướng dẫn sử dụng PHP cho các định dạng ngày tháng:

  • U = Giây kể từ Kỷ nguyên Unix
  • u = Microseconds

http://php.net/manual/en/ Chức năng.date.php


Cảm ơn giggsey vì đã chỉ ra một lỗ hổng trong câu trả lời ban đầu của tôi, thêm number_format()vào dòng sẽ khắc phục trường hợp chính xác giây. Thật tệ là nó không còn cảm thấy thanh lịch nữa ...

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

http://php.net/manual/en/ Chức năng.number-format.php


Lưu ý về múi giờ theo DaVe.

Thông thường, createFromFormat()phương pháp sẽ sử dụng múi giờ địa phương nếu múi giờ không được chỉ định.

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

Tuy nhiên, kỹ thuật được mô tả ở đây là khởi tạo đối tượng DateTime bằng cách sử dụng microtime()nó trả về số giây đã trôi qua kể từ Kỷ nguyên Unix (01/01/1970 00:00:00 GMT).

http://php.net/manual/en/ Chức năng.microtime.php

Điều này có nghĩa là đối tượng DateTime được khởi tạo ngầm định thành UTC, điều này tốt cho các tác vụ nội bộ của máy chủ chỉ muốn theo dõi thời gian đã trôi qua.

Nếu bạn cần hiển thị thời gian cho một múi giờ cụ thể thì bạn cần đặt nó cho phù hợp. Tuy nhiên, điều này nên được thực hiện như một bước riêng biệt sau khi khởi tạo ( không sử dụng tham số thứ ba của createFromFormat()) vì những lý do đã thảo luận ở trên.

Các setTimeZone()phương pháp có thể được sử dụng để thực hiện yêu cầu này.

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

Ví dụ:

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

Tạo ra kết quả sau:

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

Lưu ý rằng nếu bạn muốn nhập vào mysql, định dạng thời gian cần phải là:

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

19
Lưu ý: DateTime::createFromFormat('U.u', microtime(true));sẽ trả về false nếu microtime(true)chạy trên giây chính xác. Nó trả về '1438616239' thay vì '1438616239.000000'.
giggsey

1
Giải pháp tuyệt vời, cảm ơn bạn. Có vẻ như tôi đang mất thời gian địa phương để tạo $ bây giờ từ microtime. Bất kỳ ý tưởng?
daVe

1
@daVe Tôi đã thêm một số thông tin về múi giờ, tôi hy vọng đó là những gì bạn đang có.
ArchCodeMonkey,

1
Các number_formatluôn là cần thiết, ngay cả khi nó không phải là ngày thứ hai chính xác. Nếu không, bạn đang precisionsử dụng tùy chọn cấu hình PHP (cho "hiển thị"), tùy chọn này không đủ cao theo mặc định của PHP 7.0 gây ra mất độ chính xác (không chính xác đến từng micro giây).
Teoh Han Hui

1
Luôn cuộn xuống trong StackOverflow
tom10271

15

Đây là một cách tiếp cận ngắn hơn một chút. Thay vì làm việc để tạo ngày / giờ dạng số có độ chính xác cao, tôi chuyển đổi giá trị micro giây thành một chuỗi, xóa 0và thêm nó vào cuối chuỗi ngày / giờ. Tôi có thể dễ dàng cắt bớt số thập phân bằng cách điều chỉnh tham số độ dài chuỗi; ở đây tôi sử dụng 4để lấy mili giây, nhưng bạn có thể sử dụng 7để lấy micro giây.

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

Đối với giá trị microtime () của 0.98236000 1407400573, giá trị này trả về 08-07-14 01:08:13.982.


9

Tôi sử dụng

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

output: 2017-09-05 17:04:57.555036

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

đầu ra ví dụ:

02-06-2019 16:45:03.53811192512512

Nếu bạn cần giới hạn số chữ số thập phân thì dòng dưới đây (mgutt tín dụng) sẽ là một lựa chọn tốt. (Với mã bên dưới, 6 giới hạn số chữ số thập phân là 6)

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

đầu ra ví dụ:

02-11-2019 15:33:03.624493

Bạn đã bỏ lỡ độ chính xác và số 0 dẫn đầu trong vài giây. Vì vậy, phiên bản chính xác nên được echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));. Giải thích lý do tại sao chúng ta cần 09: stackoverflow.com/a/28739819/318765
mgutt

Bạn lại bỏ lỡ độ chính xác;)echo date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
mgutt

Nhưng hãy cẩn thận, substr()không tròn. Và kết hợp với round()nó sẽ cắt các số không ở cuối: stackoverflow.com/questions/7493305/… Đó là lý do tại sao tôi đề xuất sprintf().
mgutt

@mgutt Khi nào thì chữ số đầu tiên không phải là số 0? Về cơ bản những gì cần thiết chỉ đơn giản là xóa số 0 luôn ở đó khi lấy phần dư từ fmod bằng 1. Câu hỏi yêu cầu micro giây nhưng ở dạng chữ số thập phân của giây. Không có lý do gì để giới hạn số chữ số thập phân. Nhiều chữ số thập phân hơn chỉ đơn giản là độ chính xác tốt hơn.
ghbarratt

@mgutt Tôi đã thêm phương án thay thế được đề xuất đầu tiên của bạn cho câu trả lời của mình, giải thích rằng đó sẽ là một cách tốt để giới hạn số lượng vị trí thập phân nếu cần
ghbarratt 11/02/19

3

Nếu bạn muốn định dạng một ngày như JavaScript (new Date()).toISOString()vì một lý do nào đó, thì đây là cách bạn có thể thực hiện trong PHP:

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

Đầu ra mẫu:

2016-04-27T18:25:56.696Z

Chỉ để chứng minh rằng việc trừ đi toàn bộ số không làm giảm độ chính xác của phần thập phân:

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

PHP đã làm tròn các chữ số thập phân, nhưng nó làm tròn chúng theo cùng một cách trong cả hai trường hợp.


1
Không. Đừng sử dụng toán học về số dấu phẩy động, nó không chính xác. Cũng đừng lãng phí thời gian gọi một số chức năng. Chỉ cần sử dụng substr () để cắt ngắn ngày đã định dạng thành ba chữ số thập phân.
LS

@LS Cắt bớt sẽ không làm tròn số thập phân thứ 3, điều này có lẽ thậm chí còn không chính xác hơn. Phao không bị hỏng cho đến khi bạn đi vào các khu vực thực sự nhỏ; 3 chữ số thập phân sẽ ổn. Trên thực tế, tôi không nghĩ rằng tôi đang thay đổi độ chính xác cả, phao sẽ chính xác hơn khi bạn đến gần 0. Việc trừ đi toàn bộ số sẽ không làm thay đổi vị trí thập phân AFAIK.
mpen

Về date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));thì sao?
F8ER

@ F8ER Nếu của bạn $timeđã tính bằng mili giây, thì về mặt kỹ thuật, điều đó sẽ hoạt động. Không thích substrhack, nhưng tôi đoán nó sẽ hoạt động trong khoảng thời gian từ năm 2001 đến năm 2286.
mpen

Vâng, $timelà MS, nhưng còn 2286, ý tôi là tại sao lại nghĩ như vậy và làm thế nào để có thể thoát được như vậy?
F8ER

3

Điều này dựa trên câu trả lời từ ArchCodeMonkey.

Nhưng chỉ cần đơn giản hóa, nếu bạn chỉ muốn một cái gì đó nhanh chóng hoạt động.

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

Vì vậy, đối với tôi sau đó

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

3

Đây là một phương pháp khác mà tôi thấy thanh lịch / đơn giản hơn một chút:

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

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;

1

Đối với PHP 7.1, bạn chỉ cần thực hiện điều này:

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

Nó sẽ hiển thị là:

04-11-2018 10:54:01.321688

0

Tài liệu cho biết như sau:

Microseconds (được bổ sung trong PHP 5.2.2). Lưu ý rằng date () sẽ luôn tạo ra 000000 vì nó nhận tham số số nguyên, trong khi DateTime :: format () hỗ trợ micro giây.

Tức là, sử dụng DateTime thay thế.


6
Điều này không hoạt động! date_format (DateTime mới (), 'u') cho zero: phpfiddle.org/lite/code/ggh-mvz
Jānis Elmeris

Có theo câu trả lời ở trên (và các thử nghiệm của tôi) new DateTime()cũng sẽ trả về 0000 cho u. Nhưng nếu bạn cung cấp cho nó thời gian chính xác đến từng micro giây khi khởi tạo nó, nó sẽ hoạt động tốt.
scipilot

@scipilot ok, vậy làm thế nào để bạn làm điều đó?
Geo

@Geo xem câu trả lời được chấp nhận. new DateTime( 'Y-m-d H:i:s.'.$micro);
scipilot

0

Với PHP 7.0+ bây giờ ở đây bạn có thể làm như sau:

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

Điều này thực hiện như sau theo thứ tự:

  1. Cắt 4 số không cuối cùng khỏi chuỗi để Date()có thể xử lý ngày tháng.
  2. Sử dụng ngày để định dạng mili giây thành một chuỗi ngày giờ mà DateTime có thể hiểu được.
  3. DateTime()sau đó có thể cho phép bạn sửa đổi múi giờ bạn đang ở, nhưng hãy đảm bảo rằng múi giờ date_default_timezone_set("Timezone");được đặt trước khi bạn sử dụngDateTime() hàm và lớp.
  4. Bạn nên sử dụng một hàm tạo trong các lớp của mình để đảm bảo rằng bạn ở đúng múi giờ khi DateTime()các lớp hoặc hàm được sử dụng.

0

nếu bạn đang sử dụng Carbon, bạn có thể sử dụng thông số xác định "RFC3339_EXTENDED". hoặc tùy chỉnh nó.

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

0

Dựa trên câu trả lời @ArchCodeMonkey.

Nếu bạn có, declare(strict_types=1)bạn phải truyền đối số thứ hai thành chuỗi

nhập mô tả hình ảnh ở đây


0

Tôi phân nhánh một số cách khác nhau:

1) microtime + sscanf + date:

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

Tôi không chắc tại sao microtime () trả về 10 ký tự (0.dddddd00) cho phần micro giây nhưng có lẽ ai đó có thể cho tôi biết?

$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) Định dạng DateTime :: createFromFormat + Datetime->:

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

không hoạt động trong 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 + ngày:

$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-> định dạng:

$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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.