Làm thế nào để có được thời gian hiện tại tính bằng mili giây trong PHP?


Câu trả lời:


506

Các trả lời ngắn gọn là:

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

26
@FredrikWendt, tôi nghĩ bạn đang nhầm lẫn với time(). microtime(true)mặt khác trả về thời gian hiện tại tính bằng giây kể từ khi epoch Unix chính xác đến micro giây gần nhất (xem tài liệu tham khảo PHP). Thực sự rất dễ kiểm tra nếu bạn chạy đoạn mã trên trong một vòng lặp và hiển thị mili giây.
nguyệt quế

6
Tôi hoàn toàn làm được! :-)
Fredrik Wendt

10
Tôi thích câu trả lời ngắn gọn.
Erick Robertson

9
Không nên như vậy microtime(true) / 1000(phân chia thay vì mulitplication)?
Jordan Lev

18
@JordanLev, nó nên được nhân lên vì microtime (đúng) trả về dấu thời gian Unix trong vài giây dưới dạng nổi.
nguyệt quế

88

Sử dụng microtime. Hàm này trả về một chuỗi được phân tách bằng dấu cách. Phần đầu tiên là phần phân số của giây, phần thứ hai là phần không thể thiếu. Truyền vào trueđể lấy số:

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

Coi chừng mất chính xác nếu bạn sử dụng microtime(true).

Cũng có gettimeofdaytrả về phần micro giây như một số nguyên.

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

Vì vậy, nói chung là microtime()bằng nhau 1000*time(), phải không?
COMer

Tôi thấy, có thể có lỗi, nhưng lỗi nên ít hơn 1000, phải không?
COMer

@COMer: Bạn đang nói về biến thể nào?
kennytm

microtime(true)1000*time()
COMer

@COMer: 1000*time()sẽ không cung cấp cho bạn mili giây. microtime(true)trả về một floattrong đó có 14 chữ số chính xác. Phần giây đã mất 10, do đó còn lại 4 chữ số cho phần micro giây. Điều này là đủ vì mili giây chỉ cần thêm 3 chữ số.
kennytm

46

Câu trả lời ngắn:

Chỉ có nền tảng 64 bit!

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

[ Nếu bạn đang chạy PHP 64 bit thì hằng số PHP_INT_SIZEbằng8 ]


Câu trả lời dài:

Nếu bạn muốn hàm cân bằng tính time()bằng mili giây trước tiên, bạn phải xem xét đó là time()trả về số giây đã trôi qua kể từ "thời gian kỷ nguyên" (01/01/1970), số mili giây kể từ "thời gian kỷ nguyên" là một con số lớn và không phù hợp với số nguyên 32 bit.

Kích thước của một số nguyên trong PHP có thể là 32 hoặc 64 bit tùy thuộc vào nền tảng.

Từ http://php.net/manual/en/lingu.types.integer.php

Kích thước của một số nguyên phụ thuộc vào nền tảng, mặc dù giá trị tối đa khoảng hai tỷ là giá trị thông thường (đó là 32 bit được ký). Các nền tảng 64 bit thường có giá trị tối đa khoảng 9E18, ngoại trừ Windows, luôn là 32 bit. PHP không hỗ trợ số nguyên không dấu. Kích thước số nguyên có thể được xác định bằng cách sử dụng hằng số PHP_INT_SIZE và giá trị tối đa bằng cách sử dụng hằng số PHP_INT_MAX kể từ PHP 4.4.0 và PHP 5.0.5.

Nếu bạn có số nguyên 64 bit thì bạn có thể sử dụng hàm sau:

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

microtime() trả về số giây kể từ "thời gian kỷ nguyên" với độ chính xác lên đến micro giây với hai số cách nhau bởi khoảng trắng, như ...

0.90441300 1409263371

Số thứ hai là giây (số nguyên) trong khi số thứ nhất là phần thập phân.

Hàm trên milliseconds()lấy phần nguyên nhân nhân với1000

1409263371000

sau đó thêm phần thập phân nhân với 1000và làm tròn thành 0 số thập phân

1409263371904

Lưu ý rằng cả hai $mt[1]và kết quả của roundđược đúc thành int. Điều này là cần thiết bởi vì chúng là floats và hoạt động trên chúng mà không truyền sẽ dẫn đến hàm trả về a float.

Cuối cùng, chức năng đó chính xác hơn một chút so với

round(microtime(true)*1000);

với tỷ lệ 1:10 (xấp xỉ) trả về 1 mili giây so với kết quả chính xác. Điều này là do độ chính xác hạn chế của loại float ( microtime(true)trả về một float). Dù sao nếu bạn vẫn thích ngắn hơn round(microtime(true)*1000);tôi sẽ đề nghị đúc intkết quả.


Ngay cả khi nó vượt quá phạm vi của câu hỏi, điều đáng nói là nếu nền tảng của bạn hỗ trợ số nguyên 64 bit thì bạn cũng có thể có được thời gian hiện tại tính bằng micro giây mà không bị tràn.

Nếu thực tế 2^63 - 1(số nguyên được ký lớn nhất) chia cho 10^6 * 3600 * 24 * 365(khoảng micro giây trong một năm) sẽ cho 292471.

Đó là cùng một giá trị bạn nhận được với

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

Nói cách khác, một số nguyên 64 bit đã ký có chỗ để lưu trữ khoảng thời gian hơn 200.000 năm được đo bằng micro giây.

Bạn có thể có

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

tại sao không chỉ: `function getMilliEpoch () {$ mt = explode ('', microtime ()); trả lại $ mt [1]. chất nền ($ mt [0], 0, 5) * 1000; } `
Michael

Bây giờ có một tham số cho chức năng microtime, nếu nó được đặt thành true, nó sẽ trả về giây và mili giây kể từ ngày 1 tháng 1 năm 1970, 0 giờ 0 phút 0 giây dưới dạng float. Dưới đây là một ví dụ: microtime (đúng) // 1553260455.7242
kukko

@kukko có, nhưng do độ chính xác hạn chế của loại phao, việc tính toán số millicesond từ microtime (đúng) sẽ dẫn đến một giá trị hơi không chính xác
Paolo

42

Như những người khác đã nêu, bạn có thể sử dụng microtime()để có được độ chính xác mili giây trên dấu thời gian.

Từ ý kiến ​​của bạn, bạn dường như muốn nó như một Dấu thời gian UNIX có độ chính xác cao. Một cái gì đó giống như DateTime.Now.Tickstrong thế giới .NET.

Bạn có thể sử dụng chức năng sau để làm như vậy:

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

Đó là cách làm!
tonix

1
perrrrrinf .. ♥.
SRB cấm

Nó không trả về thời gian của máy chủ sao? Trong trường hợp của tôi, tôi thấy thời gian lưu trữ trong db là thời gian trình duyệt cục bộ của tôi. Giả sử, múi giờ sever của tôi là EST + 3 và thời gian trình duyệt của tôi là GMT + 6, trong khi tôi gửi biểu mẫu từ vị trí GMT + 6, tôi thấy thời gian lưu trữ là GMT + 6 lần tương đương mili giây. Vì vậy, vấn đề là gì? :(
Zenith

12

Sử dụng microtime(true)trong PHP 5 hoặc sửa đổi sau trong PHP 4:

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

Một cách di động để viết mã đó sẽ là:

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

đầu ra:

2016-11-19 15:12:34.346351


1
Điều này sử dụng cùng dấu thời gian:$t = gettimeofday(); echo date('Y-m-d H:i:s.',$t['sec']) . $t['usec'];
Savvas Radevic

micro giây nên được đệm bằng 0:$timeofday=gettimeofday(); echo sprintf("%s.%06d", date('Y-m-d H:i:s', $timeofday['sec']), $timeofday['usec']);
mabi

7

thử cái này:

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

Điều này hoạt động ngay cả khi bạn đang sử dụng PHP 32 bit:

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

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

Lưu ý điều này không cung cấp cho bạn số nguyên, nhưng chuỗi. Tuy nhiên, điều này hoạt động tốt trong nhiều trường hợp, ví dụ như khi xây dựng URL cho các yêu cầu REST.


Nếu bạn cần số nguyên, PHP 64 bit là bắt buộc.

Sau đó, bạn có thể sử dụng lại đoạn mã trên và chuyển sang (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

Hoặc bạn có thể sử dụng một lớp lót tốt:

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

LƯU Ý: PHP5 được yêu cầu cho chức năng này do những cải tiến với microtime () và mô-đun toán học bc cũng được yêu cầu (vì chúng tôi đang xử lý số lượng lớn, bạn có thể kiểm tra xem bạn có mô-đun trong phpinfo không).

Hy vọng điều này sẽ giúp bạn.


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

Có thực sự giống như đệm ba số không ở bên phải?
Zeeshan

Không có gì. Nó chuyển đổi cả hai phần thành mili giây và tính tổng. Vì vậy, nó là chính xác hơn so với thêm số không.
dùng3767296

1
Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. Xin vui lòng cố gắng không làm đông mã của bạn với các bình luận giải thích, điều này làm giảm khả năng đọc của cả mã và các giải thích!
Michał Perłakowski


-2

Dùng cái này:

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

Tạm biệt

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.