Convertirea marcajelor temporale în ora locală cu date_l18n()

5 apr. 2013, 21:48:15
Vizualizări: 40.7K
Voturi: 19

Am un cron job în WordPress care trimite un email periodic și salvează timestamp-ul când a fost trimis ca opțiune, și aș dori să afișez o dată pe o pagină de setări. Ceva de genul "Ultimul email a fost trimis la 'x'". Sunt pe coasta de vest a SUA, deci ora noastră este în prezent cu șapte ore în urmă față de UTC.

Output-ul așteptat de la date_i18n(), transmițându-i timestamp-ul, ar fi o dată formatată local cu o ajustare de șapte ore față de UTC. Cu toate acestea, funcția returnează ora în UTC. Chiar și încercarea de a obține ora curentă nu returnează ceea ce m-aș fi așteptat să fie output-ul corect.

De exemplu: echo date_i18n('F d, Y H:i'); afișează April 05, 2013 11:36 așa cum era de așteptat, dar echo date_i18n('F d, Y H:i',time()); afișează April 05, 2013 18:36.

Este acest comportament intenționat? Cum pot returna o dată formatată local dintr-un timestamp preexistent? Mulțumesc pentru orice ajutor.

2
Comentarii

Ai setat fusul orar în Setări->General?

vancoder vancoder
5 apr. 2013 22:16:15

Da, pe Los Angeles.

Andrew Bartel Andrew Bartel
5 apr. 2013 22:51:14
Toate răspunsurile la întrebare 7
3
36

Știu că am întârziat cu trei luni, dar funcția pe care o cauți aici este get_date_from_gmt() din WordPress.

Funcția acceptă o dată GMT/UTC în formatul Y-m-d H:i:s ca prim parametru și formatul de dată dorit ca al doilea parametru. Va converti data în fusul orar local setat în ecranul de Setări.

Exemplu de utilizare:

echo get_date_from_gmt( date( 'Y-m-d H:i:s', $my_unix_timestamp ), 'F j, Y H:i:s' );
20 iul. 2013 17:37:46
Comentarii

Mulțumesc enorm, am văzut această notificare acum. Am schimbat-o la răspunsul corect.

Andrew Bartel Andrew Bartel
22 iul. 2013 21:45:11

Am adăugat configurația pentru dată și oră: echo get_date_from_gmt ( date( 'Y-m-d H:i:s', $my_timestamp ), get_option('date_format') . ' - '. get_option('time_format') );

Nabil Kadimi Nabil Kadimi
22 iul. 2014 02:31:05

@NabilKadimi asta e o completare bună, dar tot nu traduce șirul în limba corectă. Vezi răspunsul meu pentru o funcție care ia în considerare toate cele trei setări configure: limba, fusul orar și formatul datei.

Flimm Flimm
30 mai 2019 21:13:34
7

Din codex:

current_time('timestamp') ar trebui folosit în loc de time() pentru a returna ora locală a blogului. În WordPress, PHP time() va returna întotdeauna UTC și este același cu apelarea current_time('timestamp', true).

Încearcă asta:

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

Această metodă setează data implicită PHP la opțiunea timezone_string din WP, dacă este disponibilă, pe durata scriptului.

5 apr. 2013 22:18:12
Comentarii

Corect, dar dacă am un marcaj de timp arbitrar? Să zicem de acum câteva zile, cum obțin ora ajustată în loc de ora UTC?

Andrew Bartel Andrew Bartel
5 apr. 2013 22:49:06

funcția date_i18n('F d, Y H:i', $your_timestamp) nu funcționează?

vancoder vancoder
5 apr. 2013 23:41:18

Nu, am încercat chiar și pe o instalație WP simplă din 2012 rulând doar această instrucțiune echo date_i18n('F d, Y H:i',1365194723) în partea de sus a index.php, dar îmi afișează ora UTC în loc de ora pentru Coasta de Vest a SUA.

Andrew Bartel Andrew Bartel
5 apr. 2013 23:47:57

Aveți dreptate, se pare că date_i18n este în principal pentru formatarea locală a datelor, mai degrabă decât pentru ajustarea datelor. Am actualizat răspunsul meu.

vancoder vancoder
6 apr. 2013 00:01:10

Da, speram să evit necesitatea de a seta manual fusul orar, dar dacă asta e singura metodă, așa să fie. Marcat ca răspuns, mulțumesc pentru ajutor.

Andrew Bartel Andrew Bartel
6 apr. 2013 00:21:52

WordPress apelează date_default_timezone_set( 'UTC' );, pare o idee proastă să suprascrii asta prin apelarea proprie a date_default_timezone_set, deoarece codul WordPress și plugin-urile se pot baza pe acest comportament.

Flimm Flimm
30 mai 2019 19:39:29

@Flimm are dreptate, aici, NICIOADATĂ nu schimba setarea implicită a fusului orar.

Walf Walf
30 iun. 2022 10:10:13
Arată celelalte 2 comentarii
0

date_i18n($format, $timestamp) formatează conform localității, dar nu și a fusului orar. get_date_from_gmt($datestring, $format) formatează conform fusului orar, dar nu și a localității. Pentru a obține formatarea conform atât a fusului orar cât și a localității, fac următoarele:

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

    // Data în fusul orar local.
    $date = new \DateTime(null, $timezone);
    $date->setTimestamp($timestamp);
    $date_str = $date->format('Y-m-d H:i:s');

    // Pretinde că data locală este UTC pentru a obține timestamp-ul
    // de transmis către 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);
}

Exemplu de program:

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

Rezultat pentru fusul orar Los Angeles:

Local: Aprilie 05, 2013 11:36 UTC: Aprilie 05, 2013 18:36

Referințe:

18 feb. 2014 17:34:39
0

Conversia UTC în șir de caractere în fusul orar, limba și formatul din opțiunile WordPress

Am creat o funcție bine documentată care convertește un șir de caractere cu data și ora în UTC într-un șir de caractere frumos formatat, în limba, formatul și fusul orar corect. Simțiți-vă liber să o copiați.

De exemplu, transmitând "2019-05-30 18:06:01" (în UTC) s-ar returna "Maggio 30, 2019 10:06 am".

/**
 * Dat fiind un șir de caractere cu data și ora în UTC, returnează un șir de caractere frumos formatat
 * în limba, formatul și fusul orar configurate în opțiunile WordPress.
 *
 * @param string $utc_date_and_time 
 *      ex: "2019-05-30 18:06:01"
 *      Acest argument trebuie să fie în UTC.
 * @return string 
 *      ex: "Maggio 30, 2019 10:06 am"
 *      Returnează un șir de caractere frumos formatat în limba corectă și
 *      conform setărilor administratorului.
 */
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 ) ) {
        /* Nu am testat alte formate, deci este permis doar acesta. */
        throw new InvalidArgumentException( "Se așteaptă ca argumentul să fie în formatul YYYY-MM-DD hh:mm:ss" );
    }

    $date_in_local_timezone = get_date_from_gmt( $utc_date );

    /* $date_in_local_timezone este acum ceva de genul "2019-05-30 10:06:01"
     * în fusul orar al get_option( 'timezone_string' ), configurat în
     * setările generale WordPress din interfața de administrare.
     */

    /* Din păcate, nu putem să trecem direct această valoare în date_i18n din WordPress, deoarece
     * aceasta așteaptă ca al doilea argument să fie numărul de secunde de la 1/Ian/1970
     * 00:00:00 în fusul orar al get_option( 'timezone_string' ), care nu este același lucru
     * cu un timestamp UNIX, care este numărul de secunde de la
     * 1/Ian/1970 00:00:00 GMT. */
    $seconds_since_local_1_jan_1970 =
        (new DateTime( $date_in_local_timezone, new DateTimeZone( 'UTC' ) ))
        ->getTimestamp();
    // ex: 1559210761

    /* Administratorii pot seta un format preferat pentru dată și un format preferat pentru oră
     * în setările generale WordPress din interfața de administrare, noi
     * trebuie să le preluăm. */
    $settings_format = get_option( 'date_format' ) . ' '. get_option( 'time_format' );
    // $settings_format este în acest exemplu "F j, Y g:i a"

    /* În acest exemplu, instalarea WordPress a fost setată în italiană,
     * iar rezultatul final este "Maggio 30, 2019 10:06 am" */
    return date_i18n( $settings_format, $seconds_since_local_1_jan_1970 );

}

Referințe:

  • Documentația WordPress pentru get_date_from_gmt
  • Documentația pentru DateTimeZone pe php.net
  • Documentația pentru DateTime pe php.net, inclusiv getTimestamp
  • Documentația WordPress pentru date_i18n
  • Este important de reținut că WordPress rulează date_default_timezone_set( 'UTC' ); indiferent de fusul orar selectat de administrator în interfața utilizator, așa că țineți cont de acest lucru când determinați comportamentul funcțiilor PHP încorporate. Consultați documentația pentru date_default_timezone_set pe php.net.
30 mai 2019 21:12:41
3

Marcajele temporale (timestamp) nu au fus orar, așa că aproape niciodată nu este nevoie să le manipulați matematic.

Începând cu WordPress v5.3, cea mai simplă soluție pentru marcaje temporale specifice este funcția wp_date():

$format = get_option( 'time_format' ) . ', ' . get_option( 'date_format' );
echo wp_date( $format, $your_timestamp );

Pentru data și ora curentă, utilizați funcția denumită sugestiv current_datetime:

echo current_datetime()->format( $format );
30 iun. 2022 10:54:43
Comentarii

Timestamp-urile reprezintă numărul de secunde trecute de la 1 ianuarie 1970, 00:00 UTC pentru unele definiții ale unui timestamp, sau numărul de secunde de la 1 ianuarie 1970 în fusul orar local pentru alte definiții ale unui timestamp.

Flimm Flimm
30 iun. 2022 13:14:29

@Flimm În PHP (și, prin urmare, în WordPress), timestamp-urile sunt întotdeauna în GMT. Vezi time().

Walf Walf
1 iul. 2022 07:39:00

Acesta este răspunsul corect din 2024.

Ciantic Ciantic
7 mar. 2024 17:01:20
0

Adaugă diferența de fus orar la marcajul tău de timp.

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

sau mai bine;

$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 );
16 feb. 2015 04:24:48
1

Aceasta este soluția care pare să funcționeze pe mașina mea (niciuna dintre celelalte variante nu a funcționat):

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

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

Nu utilizează date_l18n(), dar presupun că s-ar putea folosi ulterior...

28 dec. 2015 20:33:52
Comentarii

get_the_time acceptă un argument $post încă din aproximativ 2008.

Walf Walf
30 iun. 2022 11:05:56