TimeZone — cos’è, classe Foundation e fusi orari

Autore: IT Sectr Pubblicato: 2026-07-12 Tempo di lettura: 9 min

TimeZone è una classe Foundation in iOS e macOS che astrae le informazioni sui fusi orari per la corretta conversione dell’ora tra regioni geografiche. Secondo Apple Developer Documentation, 2024, TimeZone fornisce metodi per lavorare con identificatori di fusi orari (IANA Time Zone Database), offset rispetto a UTC e regole di passaggio all’ora legale. La classe è integrata con DateFormatter e Calendar, garantendo l’applicazione automatica del fuso orario corretto durante la formattazione delle date. A differenza del calcolo manuale dell’offset, TimeZone aggiorna automaticamente i dati quando cambia il fuso orario del dispositivo.

Punti chiave

  • TimeZone — una classe Foundation per lavorare con i fusi orari in iOS e macOS
  • IANA Time Zone Database — la fonte principale degli identificatori di fusi orari (America/New_York, Europe/Moscow)
  • Correzione automatica — TimeZone gestisce l’ora legale senza codice aggiuntivo
  • Integrazione con DateFormatter — il fuso orario viene applicato automaticamente durante la formattazione delle date
  • Tre tipi — locale (corrente), fisso (specificato da identificatore) e UTC

Cos’è TimeZone in Foundation?

TimeZone è un tipo valore in Swift che fornisce informazioni su un fuso orario geografico: offset UTC, nome, abbreviazione e regole di ora legale. In Objective-C, la classe si chiama NSTimeZone. Entrambe le classi si basano su IANA Time Zone Database (noto anche come database Olson), che contiene la cronologia delle modifiche dei fusi orari dal 1970.

Ogni istanza di TimeZone memorizza un identificatore di fuso orario (ad esempio Europe/Moscow), l’offset corrente in secondi da UTC, il flag isDaylightSavingTime e la data della prossima transizione. L’identificatore è la chiave primaria: durante l’inizializzazione TimeZone(identifier:), il sistema carica il record corrispondente dal database dei fusi orari del dispositivo.

Secondo IANA (2024), il database contiene oltre 600 identificatori unici di fusi orari. Apple fornisce un’istantanea di questo database con ogni versione di iOS e macOS, garantendo calcoli coerenti su tutti i dispositivi senza necessità di richieste di rete.

Come funziona TimeZone in iOS e macOS?

Architettura di TimeZone in Foundation è costruita su un sistema a due livelli: l’identificatore di fuso orario (nome leggibile) e la sua rappresentazione numerica (offset UTC). Il sistema seleziona automaticamente il fuso orario corrente dalle impostazioni del dispositivo, ma lo sviluppatore può sovrascriverlo per operazioni di formattazione specifiche.

TimeZone è strettamente legato a Calendar e DateFormatter. Durante la formattazione di una data, DateFormatter utilizza la proprietà timeZone di un’istanza TimeZone per convertire un momento assoluto nel tempo (Date) in una rappresentazione stringa nel fuso orario desiderato. Se timeZone non è impostato, viene utilizzato il fuso orario di sistema predefinito — TimeZone.current.

Tipi di istanze TimeZone

TipoInizializzazioneCaratteristiche
CorrenteTimeZone.currentSi aggiorna automaticamente al cambio di regione nelle impostazioni, tiene traccia dell’ora legale
FissoTimeZone(identifier:)Indipendente dalla regione del dispositivo. Applica costantemente l’identificatore selezionato
UTCTimeZone(secondsFromGMT: 0)Fuso orario senza correzione. Identificatore: GMT
Con offset arbitrarioTimeZone(secondsFromGMT: 10800)Offset fisso in secondi. Non considera l’ora legale

Nota importante: TimeZone(identifier:) restituisce nil per identificatori sconosciuti. Questa è una causa comune di crash dell’app — gli sviluppatori dimenticano di gestire il valore opzionale quando passano un identificatore non valido dall’input utente. Per gli identificatori IANA, le maiuscole/minuscole sono importanti: Europe/Moscow è valido, europe/moscow restituisce nil.

Formati degli identificatori di fusi orari

IANA Time Zone Database utilizza il formato “Regione/Città” (Continente/Città), dove la regione è uno dei continenti (Africa, America, Asia, Atlantic, Australia, Europe, Indian, Pacific) o un oceano, e la città è la località più popolosa nell’area di copertura del fuso orario. Questo formato garantisce unicità e leggibilità dell’identificatore.

Oltre al formato principale, TimeZone supporta tre metodi aggiuntivi di identificazione: abbreviazioni (MSK, EST, PST), codici a tre lettere dei fusi orari (GMT, UTC) e offset numerici (+0300, -0500). Tuttavia, le abbreviazioni sono ambigue: EST può significare Eastern Standard Time (GMT-5) o Eastern Summer Time (GMT+10) in Australia. Apple raccomanda di utilizzare esclusivamente identificatori IANA.

swift
import Foundation

// Ottenere tutti gli identificatori di fuso orario conosciuti
let allIdentifiers: [String] = TimeZone.knownTimeZoneIdentifiers
print("Totale fusi orari: \(allIdentifiers.count)")

// Filtrare per regione
let europeZones = allIdentifiers.filter { $0.hasPrefix("Europe/") }
print("Fusi orari europei: \(europeZones)")

// Abbreviazioni (non consigliato per la produzione)
if let moscowTimeZone = TimeZone(abbreviation: "MSK") {
    print("Secondi MSK da GMT: \(moscowTimeZone.secondsFromGMT())")
}

// Trovare identificatore per offset
let utcPlus3 = TimeZone(secondsFromGMT: 10800)
print("Identificatore: \(utcPlus3.identifier)")

Abbreviazioni in TimeZone.abbreviationDictionary contengono abbreviazioni per tutti i fusi orari conosciuti, ma questo dizionario non garantisce unicità: la chiave PST può corrispondere a America/Los_Angeles o Pacific/Pago_Pago. Per il codice di produzione, utilizzare sempre identificatori IANA.

Ora legale e TimeZone

TimeZone considera automaticamente i passaggi all’ora legale (DST) per tutte le regioni in cui è osservata. Il sistema utilizza dati storici da IANA Time Zone Database, che include date precise di transizione per ogni fuso orario. La proprietà isDaylightSavingTime restituisce true se il fuso orario si trova attualmente in ora legale.

Il metodo nextDaylightSavingTimeTransition consente di conoscere la data della prossima transizione, utile per pianificare eventi futuri. Questa funzionalità è particolarmente importante per regioni con frequenti cambiamenti delle regole DST, come Brasile o Marocco — fino al 2024, il Brasile cambiava le date di transizione annualmente e il calcolo manuale portava a errori nelle applicazioni.

Secondo Apple WWDC 2023, la libreria ICU (International Components for Unicode), che sta alla base di Foundation, aggiorna i dati DST a ogni aggiornamento di iOS. Le applicazioni non dovrebbero memorizzare nella cache i dati dell’ora legale per più di un giorno dopo un aggiornamento del sistema — il database IANA può cambiare anche senza un aggiornamento della versione del OS attraverso modifiche dei fusi orari.

swift
import Foundation

// Controllare DST per Europe/Moscow
let moscow = TimeZone(identifier: "Europe/Moscow")!
let now = Date()
let isMoscowDST = moscow.isDaylightSavingTime(for: now)
print("Mosca attualmente in DST: \(isMoscowDST)")

// Ottenere la data della prossima transizione DST
if let nextTransition = moscow.nextDaylightSavingTimeTransition(
    after: now
) {
    let dstOffset = moscow.daylightSavingTimeOffset(
        for: nextTransition
    )
    print("Prossima transizione: \(nextTransition), offset DST: \(dstOffset)s")
}

// Conversione sicura con consapevolezza DST
let newYork = TimeZone(identifier: "America/New_York")!
let offsetNY = newYork.secondsFromGMT(for: now)
print("Offset corrente di NY: \(offsetNY / 3600)h")

Sfumatura critica: secondsFromGMT(for:) considera DST per la data specificata, mentre secondsFromGMT() si applica solo all’ora corrente. Durante la formattazione di date storiche, utilizzare sempre la versione con il parametro Date: secondsFromGMT(for: someHistoricalDate). La differenza può essere di 1–2 ore, il che è fondamentale per log o dati storici.

TimeZone in Swift: esempi di codice

Formattare una data con un fuso orario specifico è il compito più comune quando si lavora con TimeZone. DateFormatter utilizza la proprietà timeZone per convertire un Date in una stringa. Se timeZone non è impostato esplicitamente, il formattatore utilizza TimeZone.current — il fuso orario impostato sul dispositivo dell’utente, che può portare a risultati imprevisti per i dati del server.

swift
import Foundation

// Formattare data in fuso orario specifico
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

let tokyo = TimeZone(identifier: "Asia/Tokyo")!
formatter.timeZone = tokyo
let tokyoTime = formatter.string(from: Date())
print("Ora di Tokyo: \(tokyoTime)")

// Identificatori disponibili per la selezione utente
let displayNames: [(String, String)] = TimeZone.knownTimeZoneIdentifiers
    .prefix(20)
    .map { ($0, TimeZone(identifier: $0)!.localizedName(
        for: .generic, locale: .current
    )) }

// Confrontare due fusi orari
let london = TimeZone(identifier: "Europe/London")!
let difference = tokyo.secondsFromGMT(for: Date())
    - london.secondsFromGMT(for: Date())
print("Differenza Tokyo-Londra: \(difference / 3600)h")

// Lavorare con dizionario delle abbreviazioni
let knownAbbrevs = TimeZone.abbreviationDictionary
for (abbr, ident) in knownAbbrevs.sorted(by: { $0.key < $1.key }).prefix(5) {
    print("\(abbr) -> \(ident)")
}

Nome localizzato di un fuso orario tramite localizedName(for:locale:) restituisce un nome leggibile nella lingua specificata. Ad esempio, per Europe/Moscow con lingua russa, il metodo restituisce il nome russo “Moskva”, e con lingua inglese — “Moscow Time”. Stili disponibili: .standard (nome standard), .daylightSaving (ora legale) e .shortGeneric (breve).

swift
import Foundation

let paris = TimeZone(identifier: "Europe/Paris")!
let nameRU = paris.localizedName(
    for: .standard,
    locale: Locale(identifier: "ru_RU")
)
print("Nome in russo: \(nameRU)")

// Verificare se la regione è nello stesso giorno
let isSameDay = Calendar.current.isDate(
    Date(),
    equalTo: Date(),
    toGranularity: .day
)
print("Stesso giorno in diversi fusi orari: \(isSameDay)")

Serializzazione dell’identificatore di fuso orario è la pratica migliore per memorizzare TimeZone in database o UserDefaults. Salvare l’identificatore (una stringa come Europe/Moscow), non l’offset in secondi o un’abbreviazione. L’offset può cambiare con le modifiche DST e le abbreviazioni sono ambigue. Ripristino: TimeZone(identifier: savedString).

Errori comuni con TimeZone

Utilizzare un offset fisso invece di un identificatore di fuso orario è l’errore più comune. TimeZone(secondsFromGMT: 10800) non considera DST, quindi per Europe/Moscow in estate, questa costruzione dà un offset errato di 1 ora. Utilizzare sempre l’identificatore IANA per le regioni con ora legale.

Gestione di nil dimenticata durante l’inizializzazione di TimeZone(identifier:) è il secondo errore più frequente. Se un utente inserisce un identificatore errato (ad esempio “moscow” invece di “Europe/Moscow”), il costruttore restituisce nil. Senza gestire il valore opzionale, l’app si blocca con un errore di runtime. Utilizzare guard let o TimeZone(identifier:) con un fallback noto.

Ignorare DST quando si lavora con date future. TimeZone.secondsFromGMT(for:) è l’unico modo corretto per ottenere l’offset per una data specifica. Usare secondsFromGMT() senza parametro per date storiche o future restituisce l’offset per il momento corrente, che potrebbe non corrispondere all’offset effettivo nella data specificata, specialmente per regioni che hanno abolito o introdotto DST.

Secondo Stack Overflow (2024), circa il 15% delle domande su DateFormatter riguarda una configurazione errata di timeZone. Uno scenario tipico: il server invia una data in UTC, lo sviluppatore la formatta senza impostare il timeZone del formattatore, e la data viene visualizzata nel fuso orario del dispositivo, creando confusione tra utenti di diverse regioni. Regola: impostare sempre esplicitamente il timeZone del formattatore per i dati del server.

Domande frequenti

Cos’è TimeZone in Foundation?

TimeZone è una classe Foundation per lavorare con i fusi orari in iOS e macOS. Fornisce informazioni sull’offset UTC, le regole dell’ora legale e gli identificatori dei fusi orari basati su IANA Time Zone Database.

Quali formati di identificatori supporta TimeZone?

Tre formati: identificatori IANA (Europe/Moscow), abbreviazioni (MSK, EST) e offset numerici (+0300). Apple raccomanda di utilizzare gli identificatori IANA come unico formato non ambiguo per il codice di produzione.

Come gestisce TimeZone l’ora legale?

Automaticamente tramite i metodi secondsFromGMT(for:) e isDaylightSavingTime(for:). TimeZone utilizza dati storici IANA, aggiornati a ogni versione di iOS, garantendo transizioni DST corrette per qualsiasi data.

Qual è la differenza tra TimeZone.current e TimeZone.system?

TimeZone.current restituisce il fuso orario selezionato dall’utente nelle impostazioni (può differire da quello geografico). TimeZone.system restituisce il fuso orario del dispositivo, determinato automaticamente dalla geolocalizzazione e non modificabile dall’utente.

Come ottenere il fuso orario corrente in Swift?

TimeZone.current restituisce il fuso orario corrente del dispositivo. Per ottenere l’identificatore, utilizzare la proprietà identifier: TimeZone.current.identifier. Per un nome localizzato, chiamare localizedName(for:locale:).

Riepilogo

  • TimeZone — una classe fondamentale di Foundation per lavorare con i fusi orari in iOS e macOS
  • Identificatori IANA — l’unico modo affidabile per specificare un fuso orario (Europe/Moscow, America/New_York)
  • Gestione automatica di DST — TimeZone gestisce correttamente l’ora legale tramite secondsFromGMT(for:)
  • Integrazione con DateFormatter — l’impostazione obbligatoria di timeZone previene la visualizzazione errata delle date
  • Nomi localizzati — il metodo localizedName(for:locale:) restituisce il nome del fuso orario nella lingua desiderata
  • Gestione degli errori — l’inizializzazione TimeZone(identifier:) restituisce nil per identificatori non validi
  • Memorizzazione degli identificatori — salvare la stringa IANA per la serializzazione, non l’offset o l’abbreviazione

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche