date_timezone_set()
Scopri come date_timezone_set() di PHP converte un oggetto DateTime in un altro fuso orario senza cambiare l'istante. Sintassi, DST ed esempi.
Introduzione
date_timezone_set() cambia il fuso orario di un oggetto DateTime esistente. In modo cruciale, non modifica l'istante sottostante nel tempo — cambia la rappresentazione dell'orologio di quell'istante. Lo stesso momento viene semplicemente riesplicitato in un fuso orario diverso, quindi le ore e i minuti visualizzati cambiano mentre il punto assoluto nella linea del tempo rimane identico.
Questo lo rende lo strumento giusto ogni volta che hai una data/ora in un fuso orario e devi mostrarla in un altro: convertire un timestamp UTC memorizzato nell'ora locale di un utente, oppure confrontare eventi registrati in regioni diverse.
date_timezone_set() è l'alias procedurale del metodo DateTime::setTimezone() — entrambi fanno esattamente la stessa cosa.
Sintassi
date_timezone_set(DateTime $object, DateTimeZone $timezone): DateTime|false$object— l'objectDateTimedi cui vuoi cambiare il fuso orario.$timezone— un objectDateTimeZoneche contiene il fuso di destinazione (ad esempionew DateTimeZone('Asia/Tokyo')).
La funzione modifica $object sul posto e restituisce la stessa istanza in caso di successo (utile per il concatenamento), oppure false in caso di errore. Poiché modifica l'object originale, non esiste una "copia" separata — è l'object di input stesso a cambiare.
Esempio di base
2023-03-03 21:00:00L'object parte alle 12:00 a Londra (Europe/London, che è UTC+0 a marzo). Tokyo è 9 ore avanti, quindi lo stesso istante viene visualizzato come 21:00. Il momento effettivo non è cambiato di nulla — solo il fuso orario in cui viene mostrato.
L'istante rimane lo stesso — cambia solo la visualizzazione
Questo è l'aspetto più importante da capire su date_timezone_set(). Confronta il valore prima e dopo la conversione:
<?php
$date = new DateTime('2023-03-03 12:00:00', new DateTimeZone('Europe/London'));
echo $date->format('Y-m-d H:i:s P'), "\n"; // before
date_timezone_set($date, new DateTimeZone('Asia/Tokyo'));
echo $date->format('Y-m-d H:i:s P'), "\n"; // after2023-03-03 12:00:00 +00:00
2023-03-03 21:00:00 +09:00L'ora dell'orologio e l'offset UTC cambiano entrambi, ma 12:00 +00:00 e 21:00 +09:00 sono lo stesso punto nel tempo. Se hai bisogno solo dell'istante assoluto (ad esempio, un timestamp UNIX), rimarrà invariato.
Se invece vuoi sostituire l'ora dell'orologio senza convertirla, non usare questa funzione — imposta l'ora direttamente con
date_time_set().
L'ora legale viene gestita automaticamente
Poiché la conversione avviene tramite un vero DateTimeZone, le regole dell'ora legale (DST) vengono applicate automaticamente. New York è UTC-5 in inverno ma UTC-4 in estate, e date_timezone_set() sceglie l'offset corretto per la data in questione:
<?php
$utc = new DateTime('2023-06-21 12:00:00', new DateTimeZone('UTC'));
date_timezone_set($utc, new DateTimeZone('America/New_York'));
echo $utc->format('Y-m-d H:i:s');2023-06-21 08:00:00A giugno, New York è in Eastern Daylight Time (UTC-4), quindi le 12:00 UTC diventano le 08:00. Esegui lo stesso codice con una data di gennaio e otterrai le 07:00 (UTC-5) — senza alcuna modifica al codice. Ecco perché dovresti sempre usare gli identificatori di zona IANA come America/New_York anziché offset fissi come -05:00.
Stile procedurale vs. orientato agli oggetti
date_timezone_set($obj, $tz) e $obj->setTimezone($tz) sono intercambiabili. La forma con metodo di solito si legge meglio e si concatena in modo naturale:
<?php
$london = (new DateTime('2023-03-03 12:00:00', new DateTimeZone('Europe/London')))
->setTimezone(new DateTimeZone('Asia/Tokyo'));
echo $london->format('Y-m-d H:i:s');2023-03-03 21:00:00Casi d'uso comuni
- Visualizzare i timestamp UTC memorizzati nel fuso orario dell'utente. Memorizza ogni timestamp in UTC, poi converti in output con
date_timezone_set()per il fuso orario preferito di ogni utente. - Normalizzare gli orari provenienti da più regioni prima di confrontarli o ordinarli.
- Creare report per area geografica, mostrando lo stesso evento in più fusi orari affiancati.
Cose a cui prestare attenzione
- Modifica l'object originale. Se hai bisogno di mantenere il valore sorgente, clonalo prima:
$copy = clone $date;poi converti$copy. - Non analizza né imposta una nuova data — si limita a riproiettare l'istante esistente. Usa
date_create()per costruire unDateTimeedate_time_set()per sovrascrivere l'ora. - Per leggere il fuso orario attualmente associato a un object, usa
date_timezone_get(). - Non confonderla con
date_default_timezone_set(), che imposta il fuso orario predefinito a livello di script per tutte le funzioni data/ora — un compito completamente diverso.
Diagramma
graph LR
A[DateTime Object] --> B((date_timezone_set))
C[Target DateTimeZone] --> B
B --> D[Same instant, new wall-clock display]