Dấu thời gian PHP thành DateTime


94

Bạn có biết làm cách nào tôi có thể chuyển đổi giá trị này thành strtotime hoặc một loại giá trị tương tự để chuyển vào đối tượng DateTime không?

Ngày tôi có:

Mon, 12 Dec 2011 21:17:52 +0000

Những gì tôi đã thử:

$time = substr($item->pubDate, -14);
$date = substr($item->pubDate, 0, strlen($time));

$dtm = new DateTime(strtotime($time));
$dtm->setTimezone(new DateTimeZone(ADMIN_TIMEZONE));
$date = $dtm->format('D, M dS');
$time = $dtm->format('g:i a');

Điều trên là không chính xác. Nếu tôi lặp lại nhiều ngày khác nhau thì tất cả đều có cùng một ngày.

Câu trả lời:


164

Bạn không cần phải biến chuỗi thành dấu thời gian để tạo DateTimeđối tượng (trên thực tế, hàm tạo của nó thậm chí không cho phép bạn làm điều này, như bạn có thể nói). Bạn có thể chỉ cần cung cấp chuỗi ngày của mình vào hàm DateTimetạo như hiện tại:

// Assuming $item->pubDate is "Mon, 12 Dec 2011 21:17:52 +0000"
$dt = new DateTime($item->pubDate);

Điều đó đang được nói, nếu bạn có một dấu thời gian mà bạn muốn sử dụng thay vì một chuỗi, bạn có thể làm như vậy bằng cách sử dụng DateTime::setTimestamp():

$timestamp = strtotime('Mon, 12 Dec 2011 21:17:52 +0000');
$dt = new DateTime();
$dt->setTimestamp($timestamp);

Chỉnh sửa (2014-05-07):

Tôi thực sự không biết điều này vào thời điểm đó, nhưng DateTimenhà xây dựng không hỗ trợ trường hợp việc tạo trực tiếp từ timestamps. Theo tài liệu này , tất cả những gì bạn cần làm là thêm trước dấu thời gian với một @ký tự:

$timestamp = strtotime('Mon, 12 Dec 2011 21:17:52 +0000');
$dt = new DateTime('@' . $timestamp);

Điều này hoạt động tuyệt vời. Tôi đã thử điều này trước đây nhưng chắc chắn đã không cho nó đủ cơ hội !!! cảm ơn :))
JREAM

18
Lưu ý rằng new DateTime('@' . $timestamp)$dt = new DateTime(); $dt->setTimestamp($timestamp)không xử lý múi giờ theo cùng một cách. Xem câu trả lời của tôi @ stackoverflow.com/questions/12038558/… để biết thêm chi tiết.
John Slegers

42

Mặc dù @drrcknlsn đúng khi khẳng định có nhiều cách để chuyển đổi chuỗi thời gian thành một hệ thống dữ liệu, nhưng điều quan trọng là phải nhận ra rằng những cách khác nhau này không xử lý múi giờ theo cùng một cách.


Lựa chọn 1 : DateTime('@' . $timestamp)

Hãy xem xét đoạn mã sau:

date_format(date_create('@'. strtotime('Mon, 12 Dec 2011 21:17:52 +0800')), 'c');

Các strtotimechút loại bỏ các thông tin múi giờ, và các date_createchức năng giả GMT ( Europe/Brussels).

Do đó, đầu ra sẽ như sau, bất kể tôi chạy nó trên máy chủ nào:

2011-12-12T13:17:52+00:00

Lựa chọn 2 : date_create()->setTimestamp($timestamp)

Hãy xem xét đoạn mã sau:

date_format(date_create()->setTimestamp(strtotime('Mon, 12 Dec 2011 21:17:52 +0800')), 'c');

Bạn có thể mong đợi điều này tạo ra cùng một đầu ra. Tuy nhiên, nếu tôi thực thi mã này từ máy chủ của Bỉ, tôi nhận được kết quả sau:

2011-12-12T14:17:52+01:00

Không giống như date_createhàm, setTimestampphương pháp này giả định múi giờ của máy chủ ( 'Europe/Brussels'trong trường hợp của tôi) chứ không phải GMT.


Đặt múi giờ của bạn một cách rõ ràng

Nếu bạn muốn đảm bảo đầu ra của mình khớp với múi giờ của đầu vào, tốt nhất bạn nên đặt nó một cách rõ ràng.

Hãy xem xét đoạn mã sau:

date_format(date_create('@'. strtotime('Mon, 12 Dec 2011 21:17:52 +0800'))->setTimezone(new DateTimeZone('Asia/Hong_Kong')), 'c')

Bây giờ, hãy xem xét đoạn mã sau:

date_format(date_create()->setTimestamp(strtotime('Mon, 12 Dec 2011 21:17:52 +0800'))->setTimezone(new DateTimeZone('Asia/Hong_Kong')), 'c')

Bởi vì chúng tôi đặt rõ ràng múi giờ của đầu ra khớp với múi giờ của đầu vào, cả hai sẽ tạo ra cùng một đầu ra (đúng):

2011-12-12T21:17:52+08:00

27

Có lẽ giải pháp đơn giản nhất chỉ là:

DateTime::createFromFormat('U', $timeStamp);

Trong đó 'U' có nghĩa là kỷ nguyên Unix. Xem tài liệu: http://php.net/manual/en/datetime.createfromformat.php


2
Phương pháp này cũng bỏ qua múi giờ
Bouke Versteegh

2
@BoukeVersteegh và cái nào không?
forsberg

2
@BoukeVersteegh Đây là dấu thời gian Unix !, nó giải phóng bạn khỏi các vấn đề về múi giờ trong khi tạo đối tượng . chỉ cần sử dụng ->setTimezoneđể đặt múi giờ thích hợp trước khi gọi->format()
Kế toán م

1
@BoukeVersteegh Kiểm tra lưu ý lớn này từ hướng dẫn sử dụng PHP "Tham số $ timezone và múi giờ hiện tại bị bỏ qua khi tham số $ time là dấu thời gian UNIX (ví dụ: @ 946684800) hoặc chỉ định múi giờ (ví dụ: 2010-01-28T15: 00: 00 + 02: 00). "
Kế toán م

1
Dấu thời gian Unix không có múi giờ, theo định nghĩa, chúng luôn là UTC
the_nuts

0

nó là giải pháp của tôi:

    function changeDateTimezone($date, $from='UTC', $to='Asia/Tehran', $targetFormat="Y-m-d H:i:s")
    {
        $date = new DateTime($date, new DateTimeZone($from));
        $date->setTimeZone(new DateTimeZone($to));
        return $date->format($targetFormat);
    }
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.