Marca de tiempo PHP en DateTime

94

¿Sabes cómo puedo convertir esto en un strtotime o un tipo de valor similar para pasar al objeto DateTime ?

La fecha que tengo:

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

Lo que he probado:

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

Lo anterior no es correcto. Si recorro muchas fechas diferentes, es la misma fecha.

JREAM
fuente

Respuestas:

163

No necesitas convertir la cadena en una marca de tiempo para crear el DateTimeobjeto (de hecho, su constructor ni siquiera te permite hacer esto, como puedes ver). Simplemente puede ingresar su cadena de fecha en el DateTimeconstructor tal como está:

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

Dicho esto, si tiene una marca de tiempo que desea usar en lugar de una cadena, puede hacerlo usando DateTime::setTimestamp():

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

Editar (2014-05-07):

En realidad no era consciente de esto en el momento, pero el DateTimeconstructor lo hace de soporte Creación casos directamente de las marcas de tiempo. De acuerdo con esta documentación , todo lo que necesita hacer es anteponer un @carácter a la marca de tiempo :

$timestamp = strtotime('Mon, 12 Dec 2011 21:17:52 +0000');
$dt = new DateTime('@' . $timestamp);
FtDRbwLXw6
fuente
Esto funciona muy bien. ¡Lo había intentado anteriormente, pero no debí haberle dado suficiente oportunidad! gracias :))
JREAM
18
Tenga en cuenta eso new DateTime('@' . $timestamp) y $dt = new DateTime(); $dt->setTimestamp($timestamp)no trate las zonas horarias de la misma manera. Consulte mi respuesta @ stackoverflow.com/questions/12038558/… para obtener más detalles.
John Slegers
42

Si bien @drrcknlsn tiene razón al afirmar que hay varias formas de convertir una cadena de tiempo en un tiempo de datos, es importante darse cuenta de que estas diferentes formas no tratan con las zonas horarias de la misma manera.


Opción 1 : DateTime('@' . $timestamp)

Considere el siguiente código:

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

El strtotimebit elimina la información de la zona horaria y la date_createfunción asume GMT ( Europe/Brussels).

Como tal, el resultado será el siguiente, sin importar en qué servidor lo ejecute:

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

Opcion 2 : date_create()->setTimestamp($timestamp)

Considere el siguiente código:

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

Es de esperar que esto produzca el mismo resultado. Sin embargo, si ejecuto este código desde un servidor belga, obtengo el siguiente resultado:

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

A diferencia de la date_createfunción, el setTimestampmétodo asume la zona horaria del servidor ( 'Europe/Brussels'en mi caso) en lugar de GMT.


Establecer explícitamente su zona horaria

Si desea asegurarse de que su salida coincida con la zona horaria de su entrada, es mejor establecerla explícitamente.

Considere el siguiente código:

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

Ahora, considere también el siguiente código:

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

Debido a que establecemos explícitamente la zona horaria de la salida para que coincida con la de la entrada, ambos crearán la misma salida (correcta):

2011-12-12T21:17:52+08:00
John Slegers
fuente
27

Probablemente la solución más simple sea simplemente:

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

Donde 'U' significa época Unix. Ver documentos: http://php.net/manual/en/datetime.createfromformat.php

Forsberg
fuente
2
Este método también ignora la zona horaria
Bouke Versteegh
2
@BoukeVersteegh y ¿cuál no?
forsberg
2
@BoukeVersteegh ¡Esta es una marca de tiempo de Unix !, lo libera de problemas de zonas horarias mientras crea el objeto . solo use ->setTimezonepara establecer la zona horaria preferible antes de llamar->format()
Contador م
1
@BoukeVersteegh Verifique esta gran nota del manual de PHP "El parámetro $ timezone y la zona horaria actual se ignoran cuando el parámetro $ time es una marca de tiempo UNIX (por ejemplo, @ 946684800) o especifica una zona horaria (por ejemplo, 2010-01-28T15: 00: 00 + 02: 00). "
Contador م
1
Las marcas de tiempo de Unix no tienen zonas horarias, siempre son UTC por definición
the_nuts
0

es mi solucion:

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