Come ottenere l'impostazione del fuso orario di WordPress?
Qualcuno può dirmi come ottenere il fuso orario che è impostato nell'amministrazione di WordPress?
Ad esempio, se il blog è impostato sul fuso orario orientale, ho bisogno che venga stampata esattamente questa stringa:
US/Eastern
Questo è per una funzione che risiede in functions.php nel mio tema.

se hai bisogno del gmt_offset allora
<?php echo get_option('gmt_offset'); ?>
questo ti restituirà un numero intero come 2 o -2.
e se hai bisogno della stringa del fuso orario usa
<?php echo get_option('timezone_string'); ?>
questo ti restituirà una stringa come America/Indianapolis

La mia timezone_string è nel database ma è vuota, anche dopo aver selezionato un fuso orario diverso nella pagina delle impostazioni. Quale potrebbe essere il motivo? (WP3.6)

gmt_offset tiene conto dell'ora legale in base all'impostazione del fuso orario del sito?

La situazione sfortunata è che ci sono effettivamente due diverse opzioni:
- Il più recente
timezone_string
, che salva il fuso orario in stile PHP. - Il più vecchio
gmt_offset
, che salva l'offset numerico in float in ore.
Ma negli ambienti più recenti, timezone_string
in realtà sovrascrive gmt_offset
, il valore restituito da quest'ultimo sarà basato sul primo. Tuttavia, il contrario non è vero — gmt_offset
potrebbe essere valido, mentre timezone_string
potrebbe essere vuoto.
WordPress 5.3 ha introdotto la funzione wp_timezone()
, che astrae questo problema e restituisce un oggetto DateTimeZone
valido, indipendentemente dalle impostazioni sottostanti di WP.
Prima di ciò, avevo implementato una soluzione nella mia libreria WpDateTime
(per completezza, questa è stata utilizzata come base per l'implementazione nel core):
class WpDateTimeZone extends \DateTimeZone {
/**
* Determina il fuso orario dalle opzioni di WordPress e lo restituisce come oggetto.
*
* @return static
*/
public static function getWpTimezone() {
$timezone_string = get_option( 'timezone_string' );
if ( ! empty( $timezone_string ) ) {
return new static( $timezone_string );
}
$offset = get_option( 'gmt_offset' );
$hours = (int) $offset;
$minutes = abs( ( $offset - (int) $offset ) * 60 );
$offset = sprintf( '%+03d:%02d', $hours, $minutes );
return new static( $offset );
}
}

Questa dovrebbe essere la risposta accettata. Le persone potrebbero incontrare bug se si affidano esclusivamente a get_option('timezone_string').

L'uso di (int)
per $hours e floor
per $minutes non è problematico? Secondo la documentazione, (int)
e floor
sono quasi la stessa cosa, eccetto che (int)
arrotonderà -4.5 a -4 mentre floor
lo arrotonderà a -5. Sembra che questo potrebbe dare offset di fuso orario negativi errati?

@Mikepote sì, questo è stato risolto nella libreria molto tempo fa, è solo una copia obsoleta del codice nella risposta qui.

Oh mio dio perché l'hanno implementato in questo modo... Mi è costato un'ora intera tilt

La libreria gestisce il fatto che un fuso orario può contenere più offset? Vedi: https://stackoverflow.com/tags/timezone/info

Consulta la pagina di riferimento delle opzioni. L'opzione gmt_offset
restituisce un numero intero. Ad esempio, se il fuso orario è impostato sull'ora orientale (es. America/New_York), gmt_offset
dovrebbe essere -5.

Considerando che WordPress memorizza la stringa del fuso orario nella tabella delle opzioni, puoi utilizzare l'approccio orientato agli oggetti per ottenere l'ora corretta sul tuo sito WordPress:
$tz = new DateTimeZone(get_option('timezone_string'));
$dt = new DateTime("now", $tz);
$page .= "<p> DateTime " . $dt->format("Y-m-d H:i:s") . "</p>";

Non pensare che otterrai una stringa come US/Eastern senza memorizzare tutte le stringhe che desideri in un array e riferirsi ad esse. Utilizzando PHP puoi ottenere l'abbreviazione del fuso orario, cioè EST; e se hai questi valori memorizzati in un array con le stringhe che vuoi, puoi cercarle.
<?php date_default_timezone_set(get_option('timezone_string'));
echo date('T'); // restituirà una stringa di tre caratteri come "EST"
$timezones = array (
'EST' => 'US/Eastern',
'CST' => 'US/Central',
// ecc, ecc, ecc.
);
echo $timezones [ date('T') ]; // dovrebbe essere quello che desideri.
?>

Questo è inutile. Gli standard dei fusi orari fanno parte di PHP dalla versione 5.2, così come l'oggetto DateTimeZone e le relative funzioni standard.

Per aggiungere a Bainternet (sto aggiungendo questo come risposta perché non posso commentare -- ho meno di 50 punti su WP Development stack).
WordPress memorizzerà una stringa del fuso orario solo se selezioni una stringa del fuso orario nelle impostazioni generali. La selezione UTF è quella predefinita nell'elenco, ma puoi scorrere verso l'alto fino alle stringhe del fuso orario. Se imposti una stringa del fuso orario, sia l'UTF che la stringa del fuso orario verranno impostati. Saranno uguali (significa che l'UTF viene reimpostato sulla nuova zona quando selezioni un fuso orario con stringa del fuso orario).
(WordPress 4)

Come ha detto Rarst, ora puoi usare wp_timezone()
che restituisce un oggetto fuso orario.
Oppure per ottenere il fuso orario come stringa, wp_timezone_string()
, che restituisce 'Europe/Rome', 'UTC', o l'offset UTC come '-6:00'.
E se vuoi l'abbreviazione, wp_date('T')
restituisce anche il fuso orario localizzato.

Ci sono alcune opzioni, nessuna delle quali funziona davvero bene. Questo è un bug di WordPress, ed è veramente fastidioso perché l'orario è sbagliato a meno che non si imposti il sito su UTC... il che è confusionario e non sempre nemmeno possibile.
Questo codice successivo penso funzioni solo se si sceglie il proprio fuso orario (sotto Impostazioni -> Generale nell'admin) come una città nominata invece che con un offset GMT. Non l'ho testato ma è molto possibile che get_option('gmt_offset')
sia impostato quando get_option('timezone_string')
non lo è.
date_default_timezone_set(get_option('timezone_string'));
Lo svantaggio di questo è che WordPress assume che PHP sia impostato su UTC quando crea timestamp mysql, quindi puoi scombussolare un po' il tuo database ogni volta che cambi fuso orario! Senza contare che altri plugin WP potrebbero assumere che l'ambiente PHP sia sempre in UTC.
Quindi, se vuoi solo un orario corretto -- puoi forzare il tuo timestamp a essere in UTC con:
get_post_time('c', true); //dovrebbe funzionare per oggetti non post.
Sfortunatamente, sebbene corretto, farà sì che il fuso orario venga impostato su UTC.
E nota che non puoi usare sia il flag "true" che la funzione timezone_set di default.
Qualsiasi soluzione corretta sarà uno snippet di codice che tiene conto sia di gmt_offset
CHE di timezone_string
e li usa per impostare un fuso orario su qualche input. WP assume che PHP sia impostato su UTC quando crea timestamp mysql, e questo potrebbe rompere altri plugin.
C'è una soluzione del genere su https://www.skyverge.com/blog/down-the-rabbit-hole-wordpress-and-timezones/ ma, ancora una volta, questo è un BUG, quindi dovresti usare il codice get_post_time($date_format, TRUE)
per ottenere un timestamp che sia effettivamente corretto.
