Відмітка часу PHP у DateTime


94

Чи знаєте ви, як я можу перетворити це на strtotime або подібний тип значення для передачі в об'єкт DateTime ?

Дата у мене:

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

Що я пробував:

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

Вищевказане не є правильним. Якщо я прокручую безліч різних дат, це однакові дати.

Відповіді:


163

Для того, щоб створити DateTimeоб’єкт, вам не потрібно перетворювати рядок у позначку часу (насправді, його конструктор навіть не дозволяє вам цього робити, як ви можете зрозуміти). Ви можете просто подати рядок дати в DateTimeконструктор як є:

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

З огляду на це, якщо у вас є відмітка часу, яку ви хочете використовувати замість рядка, ви можете зробити це, використовуючи DateTime::setTimestamp():

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

Редагувати (07.05.2014):

Я на насправді не знав про це в той час, але DateTimeконструктор робить підтримку примірників створення безпосередньо з тимчасових міток. Згідно з цією документацією , все, що вам потрібно зробити, це додати позначку часу @символом:

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

Це чудово працює. Я пробував це раніше, але, мабуть, не дав йому достатньо шансів !!! спасибі :))
JREAM

18
Зверніть увагу, new DateTime('@' . $timestamp) і $dt = new DateTime(); $dt->setTimestamp($timestamp)не майте справу з часовими поясами однаково. Детальнішу інформацію див. У моїй відповіді @ stackoverflow.com/questions/12038558/… .
John Slegers,

42

Незважаючи на те, що @drrcknlsn правильно стверджувати, що існує кілька способів перетворити рядок часу в час даних, важливо усвідомити, що ці різні способи не мають однакової роботи з часовими поясами.


Варіант 1: DateTime('@' . $timestamp)

Розглянемо такий код:

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

strtotimeБіт виключає інформацію часового поясу, а date_createфункція приймає GMT ( Europe/Brussels).

Таким чином, результат буде таким, незалежно від того, на якому сервері я його запускаю:

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

Варіант 2: date_create()->setTimestamp($timestamp)

Розглянемо такий код:

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

Ви можете очікувати, що це дасть той самий результат. Однак, якщо я виконую цей код з бельгійського сервера, я отримую такий результат:

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

На відміну від date_createфункції, setTimestampметод передбачає часовий пояс сервера ( 'Europe/Brussels'у моєму випадку), а не GMT.


Явно встановивши свій часовий пояс

Якщо ви хочете переконатися, що ваш результат відповідає часовому поясу вашого введення, найкраще встановити це явно.

Розглянемо такий код:

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

Тепер також розглянемо такий код:

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

Оскільки ми чітко встановили часовий пояс виходу, щоб він відповідав вхідному, обидва створять однаковий (правильний) результат:

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

27

Напевно, найпростішим рішенням є просто:

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

Де 'U' означає епоху Unix. Див. Документи: http://php.net/manual/en/datetime.createfromformat.php


2
Цей метод також ігнорує часовий пояс
Bouke Versteegh

2
@BoukeVersteegh, а який ні?
forsberg

2
@BoukeVersteegh Це мітка часу Unix! Вона звільняє вас від проблем з часовими поясами під час створення об’єкта . просто використовуйте ->setTimezoneдля встановлення ->format()
Бухгалтер م

1
@BoukeVersteegh Перевірте цю велику примітку з посібника PHP "Параметр $ timezone і поточний часовий пояс ігноруються, коли параметр $ time або є міткою часу UNIX (наприклад, @ 946684800), або вказує часовий пояс (наприклад, 2010-01-28T15: 00: 00 + 02: 00). "
Бухгалтер م

1
Мітки часу Unix не мають часових поясів, вони завжди є UTC за визначенням
the_nuts

0

це моє рішення:

    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);
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.