Conversión de marcas de tiempo a hora local con date_l18n ()

15

Tengo un trabajo cron de WordPress que envía un correo electrónico periódicamente y guarda la marca de tiempo cuando se envió como una opción, y me gustaría mostrar una fecha en una página de configuración. Algo así como: "El último correo electrónico se envió en 'x'". Estoy en la costa oeste de los EE. UU., Por lo que nuestro tiempo es actualmente de siete horas fuera de UTC.

Mi salida esperada de date_i18n (), pasando la marca de tiempo, sería una fecha formateada localmente con un ajuste de siete horas desde UTC. Sin embargo, devuelve la hora en UTC. Incluso tratar de obtener la hora actual no devuelve lo que creo que sería el resultado esperado.

Por ejemplo: echo date_i18n('F d, Y H:i');salidas 05 de abril de 2013 11:36 como se esperaba, pero echo date_i18n('F d, Y H:i',time());salidas 05 de abril de 2013 18:36.

¿Es esto intencional? ¿Cómo puedo devolver una fecha con formato local de una marca de tiempo preexistente? Gracias por cualquier ayuda.

Andrew Bartel
fuente
¿Ha configurado su zona horaria en Configuración-> General?
vancoder
Si a Los Angeles.
Andrew Bartel

Respuestas:

31

Sé que llego tres meses tarde, pero la función que quieres aquí es WordPress ' get_date_from_gmt().

La función acepta una fecha GMT / UTC en Y-m-d H:i:sformato como primer parámetro y el formato de fecha deseado como segundo parámetro. Convertirá su fecha a la zona horaria local como se establece en la pantalla Configuración.

Ejemplo de uso:

echo get_date_from_gmt( date( 'Y-m-d H:i:s', $my_unix_timestamp ), 'F j, Y H:i:s' );

John Blackbourn
fuente
2
Gracias asesinas, vi esta ventana emergente en mis notificaciones hace un momento. Lo cambié a la respuesta correcta.
Andrew Bartel
1
echo get_date_from_gmt ( date( 'Y-m-d H:i:s', $my_timestamp ), get_option('date_format') . ' - '. get_option('time_format') );
Agregué la
@NabilKadimi es una gran adición, pero aún no traduce la cadena al idioma correcto. Vea mi respuesta para una función que tiene en cuenta los tres idiomas configurados, la zona horaria y el formato de fecha.
Flimm
5

Del códice :

current_time ('timestamp') debe usarse en lugar de time () para devolver la hora local del blog. En WordPress, el tiempo de PHP () siempre devolverá UTC y es lo mismo que llamar a current_time ('marca de tiempo', verdadero).

Prueba esto:

define( 'MY_TIMEZONE', (get_option( 'timezone_string' ) ? get_option( 'timezone_string' ) : date_default_timezone_get() ) );
date_default_timezone_set( MY_TIMEZONE );
echo date_i18n('F d, Y H:i', 1365194723);

Esto establece la fecha predeterminada de PHP en la opción timezone_string de WP, si está disponible, durante la duración del script.

Vancoder
fuente
1
Correcto, pero ¿qué pasa si tengo una marca de tiempo arbitraria? Digamos que hace un par de días, ¿cómo obtengo la hora ajustada en lugar de la hora UTC?
Andrew Bartel
hace date_i18n('F d, Y H:i', $your_timestamp)que no funcione?
vancoder
No, incluso lo probé en una instalación de WP de vainilla con 2012 solo ejecutando esta echo date_i18n('F d, Y H:i',1365194723)declaración en la parte superior de index.php, que me da UTC en lugar de tiempo en la costa oeste de EE. UU.
Andrew Bartel
Tiene razón, parece que date_i18n es principalmente para el formato local de fechas, en lugar del ajuste de fecha. He actualizado mi respuesta.
vancoder
Sí, esperaba evitar tener que configurar la zona horaria manualmente, pero si esa es la única forma, que así sea. Marcado como respondido, gracias por la ayuda.
Andrew Bartel
2

date_i18n($format, $timestamp)formatos según la configuración regional, pero no la zona horaria. get_date_from_gmt($datestring, $format)formatos según la zona horaria, pero no la configuración regional. Para obtener el formato de acuerdo con la zona horaria y la configuración regional, estoy haciendo lo siguiente:

function local_date_i18n($format, $timestamp) {
    $timezone_str = get_option('timezone_string') ?: 'UTC';
    $timezone = new \DateTimeZone($timezone_str);

    // The date in the local timezone.
    $date = new \DateTime(null, $timezone);
    $date->setTimestamp($timestamp);
    $date_str = $date->format('Y-m-d H:i:s');

    // Pretend the local date is UTC to get the timestamp
    // to pass to date_i18n().
    $utc_timezone = new \DateTimeZone('UTC');
    $utc_date = new \DateTime($date_str, $utc_timezone);
    $timestamp = $utc_date->getTimestamp();

    return date_i18n($format, $timestamp, true);
}

Programa de ejemplo:

$format = 'F d, Y H:i';
$timestamp = 1365186960;
$local = local_date_i18n($format, $timestamp);
$gmt = date_i18n($format, $timestamp);
echo "Local: ", $local, " UTC: ", $gmt;

Salida para la zona horaria de Los Ángeles:

Local: 05 de abril de 2013 11:36 UTC: 05 de abril de 2013 18:36

Referencias

antonakos
fuente
0

Agregue compensación de zona horaria a su marca de tiempo.

$offset = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
return date_i18n( get_option( 'date_format' ), $ts + $offset );

o mejor;

$tz = new DateTimeZone( get_option( 'timezone_string' ) );
$offset_for_that_time = timezone_offset_get ( $tz , new DateTime("@{$ts}") );
return date_i18n ( get_option( 'date_format' ), $ts + offset_for_that_time );
ecabuk
fuente
0

Convertir UTC a cadena en zona horaria, idioma y formato en las opciones de WordPress

He creado una función de buen documento que convierte una cadena de fecha y hora en UTC en una bonita cadena de fecha y hora en el idioma, formato y zona horaria correctos. Siéntase libre de copiarlo.

Por ejemplo, pasar "2019-05-30 18:06:01"(en UTC) volvería "Maggio 30, 2019 10:06 am".

/**
 * Given a string with the date and time in UTC, returns a pretty string in the
 * configured language, format and timezone in WordPress' options.
 *
 * @param string $utc_date_and_time 
 *      e.g: "2019-05-30 18:06:01"
 *      This argument must be in UTC.
 * @return string 
 *      e.g: "Maggio 30, 2019 10:06 am"
 *      This returns a pretty datetime string in the correct language and
 *      following the admin's settings.
 */
function pretty_utc_date( string $utc_date ): string {
    if (! preg_match( '/^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$/', $utc_date ) ) {
        /* I have not tested other formats, so only this one allowed. */
        throw new InvalidArgumentException( "Expected argument to be in YYYY-MM-DD hh:mm:ss format" );
    }

    $date_in_local_timezone = get_date_from_gmt( $utc_date );

    /* $date_in_local_timezone is now something like "2019-05-30 10:06:01"
     * in the timezone of get_option( 'timezone_string' ), configured in
     * WordPress' general settings in the backend user interface.
     */

    /* Unfortunately, we can't just pass this to WordPress' date_i18n, as that
     * expects the second argument to be the number of seconds since 1/Jan/1970
     * 00:00:00 in the timezone of get_option( 'timezone_string' ), which is not the
     * same as a UNIX epoch timestamp, which is the number of seconds since
     * 1/Jan/1970 00:00:00 GMT. */
    $seconds_since_local_1_jan_1970 =
        (new DateTime( $date_in_local_timezone, new DateTimeZone( 'UTC' ) ))
        ->getTimestamp();
    // e.g: 1559210761

    /* Administrators can set a preferred date format and a preferred time
     * format in WordPress' general settings in the backend user interface, we
     * need to retrieve that. */
    $settings_format = get_option( 'date_format' ) . ' '. get_option( 'time_format' );
    // $settings_format is in this example "F j, Y g:i a"

    /* In this example, the installation of WordPress has been set to Italian,
     * and the final result is "Maggio 30, 2019 10:06 am" */
    return date_i18n( $settings_format, $seconds_since_local_1_jan_1970 );

}

Referencias

Flimm
fuente
-1

Esto es lo que parece funcionar en mi máquina (ninguna de las otras cosas funcionó):

$tz = new DateTimeZone(get_option('timezone_string'));
$dtz = new DateTimeZone('GMT');
foreach($posts as $key => $post){
    $gmt_date = DateTime::createFromFormat('Y-m-d H:i:s', $post->PostDateGMT, $dtz);
    $gmt_date->setTimeZone($tz);
    $posts[$key]->PostDateGMT = $gmt_date->format('Y-m-d H:i:s');
}

Código original: https://www.simonholywell.com/post/2013/12/convert-utc-to-local-time/

No está usando, date_l18n()pero supongo que uno podría usarlo más adelante ...

Ninguno
fuente