Convertendo carimbos de data e hora em horário local com date_l18n ()

15

Eu tenho um trabalho cron do WordPress que envia um email periodicamente e salva o carimbo de data e hora quando ele foi enviado como opção, e eu gostaria de exibir uma data em uma página de configurações. Algo como "O último email foi enviado em 'x'". Estou na costa oeste dos EUA, então nosso horário é atualmente de sete horas fora do UTC.

Minha saída esperada de date_i18n (), passando a data e hora, seria uma data formatada localmente com um ajuste de sete horas do UTC. No entanto, ele retorna a hora no UTC. Mesmo tentando obter o tempo atual não retorna o que eu pensaria que seria o resultado esperado.

Por exemplo: echo date_i18n('F d, Y H:i');gera 05 de abril de 2013 11:36 conforme o esperado, mas echo date_i18n('F d, Y H:i',time());gera 05 de abril de 2013 18:36.

Isso é intencional? Como posso retornar uma data formatada localmente a partir de um carimbo de data / hora preexistente? Obrigado por qualquer ajuda.

Andrew Bartel
fonte
Você definiu seu fuso horário em Configurações-> Geral?
vancoder
Sim, para Los Angeles.
Andrew Bartel

Respostas:

31

Sei que estou com três meses de atraso, mas a função que você deseja aqui é o WordPress ' get_date_from_gmt().

A função aceita uma data GMT / UTC no Y-m-d H:i:sformato como o primeiro parâmetro e o formato de data desejado como o segundo parâmetro. Ele converterá sua data para o fuso horário local, conforme definido na tela Configurações.

Exemplo 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
fonte
2
Killer obrigado, vi esse pop-up em minhas notificações agora. Eu mudei para a resposta correta.
Andrew Bartel
1
Eu adicionei a configuração de data e hora: echo get_date_from_gmt ( date( 'Y-m-d H:i:s', $my_timestamp ), get_option('date_format') . ' - '. get_option('time_format') );
Nabil Kadimi
@NabilKadimi é uma ótima adição, mas ainda não traduz a string para o idioma correto. Veja minha resposta para uma função que leva em consideração os três idiomas configurados, fuso horário e formato de data.
Flimm
5

Do codex :

current_time ('timestamp') deve ser usado no lugar de time () para retornar a hora local do blog. No WordPress, o time () do PHP sempre retornará o UTC e é o mesmo que chamar current_time ('timestamp', true).

Tente o seguinte:

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

Isso define a data padrão do PHP para a opção timezone_string do WP, se disponível, durante o script.

vancoder
fonte
1
Certo, mas e se eu tiver um carimbo de data e hora arbitrário? Digamos, há alguns dias, como obtenho a hora ajustada em vez da hora UTC?
Andrew Bartel
se date_i18n('F d, Y H:i', $your_timestamp)não funcionar?
vancoder
Não, até tentei em uma instalação WP baunilha com 2012 apenas executando esta echo date_i18n('F d, Y H:i',1365194723)declaração no topo do index.php, que me dá o tempo UTC, em vez da costa oeste dos EUA.
Andrew Bartel
Você está certo, parece que date_i18n é principalmente para formatação local de datas, em vez de ajuste de data. Eu atualizei minha resposta.
vancoder
Sim, eu esperava evitar ter que definir o fuso horário manualmente, mas se esse for o único caminho, que assim seja. Marcado como respondido, obrigado pela ajuda.
Andrew Bartel
2

date_i18n($format, $timestamp)formatos de acordo com a localidade, mas não o fuso horário. get_date_from_gmt($datestring, $format)formatos de acordo com o fuso horário, mas não a localidade. Para obter a formatação de acordo com o fuso horário e a localidade, estou fazendo o seguinte:

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

Exemplo de programa:

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

Saída para o fuso horário de Los Angeles:

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

Referências:

antonakos
fonte
0

Adicione o deslocamento do fuso horário ao seu registro de data e hora.

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

ou melhor;

$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
fonte
0

Convertendo UTC em string no fuso horário, idioma e formato nas opções do WordPress

Eu criei uma função de documento que converte uma string de data e hora no UTC em uma bonita string de data e hora no idioma, formato e fuso horário corretos. Sinta-se livre para copiá-lo.

Por exemplo, a passagem "2019-05-30 18:06:01"(no UTC) retornaria "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 );

}

Referências:

Flimm
fonte
-1

Isto é o que parece funcionar na minha máquina (nenhuma das outras coisas funcionou):

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

Não está usando, date_l18n()mas acho que alguém poderia usá-lo mais tarde ...

Ninguém
fonte