Data e ora nello sviluppo mobile: cosa sono, quali formati e come lavorare

Autore: IT Sectr Pubblicato: 2026-07-22 Tempo di lettura: 11 min

Data e ora nello sviluppo mobile — uno dei temi chiave dell'ingegneria mobile. iOS utilizza DateFormatter e ISO8601DateFormatter, Android utilizza DateTimeFormatter e LocalDate da java.time. Secondo Android Developer Docs, la scelta corretta dell'API mobile per la formattazione di data e ora influisce direttamente sulle prestazioni e sulla corretta visualizzazione in diversi fusi orari.

Punti chiave

  • DateFormatter su iOS — potente, ma lento se creato frequentemente. Mantieni in cache le istanze o usa ISO8601DateFormatter per il formato ISO 8601.
  • DateTimeFormatter su Android — formattatore thread-safe di java.time. Ha sostituito il deprecato SimpleDateFormat a partire dall'API 26.
  • ThreeTenABP — backport di java.time per Android API inferiore a 26. Aggiunge LocalDate, ZonedDateTime e DateTimeFormatter sui dispositivi vecchi.
  • TimeZone — fondamentale per convertire UTC in ora locale. Archivia l'ora in UTC, mostra nel fuso orario dell'utente.
  • Unix Timestamp — formato standard di archiviazione del tempo. La sincronizzazione via NTP garantisce precisione millisecondo.

Data e ora su iOS: DateFormatter e ISO8601DateFormatter

Su iOS, data e ora vengono tradizionalmente formattate tramite DateFormatter di Foundation. Questa classe converte Date in stringa e viceversa utilizzando un pattern, una locale e un fuso orario specificati. Il problema principale di DateFormatter — non è thread-safe e viene creato lentamente, quindi nel codice mobile le istanze devono essere messe in cache. La data nello sviluppo mobile su iOS richiede il formattatore corretto.

DateFormatter e prestazioni

La creazione di un DateFormatter richiede circa 1 millisecondo a causa dell'analisi del pattern dateFormat, del caricamento della locale e della determinazione del fuso orario. Quando si formatta un elenco di centinaia di date, la creazione ripetuta porta a ritardi evidenti nell'interfaccia utente. La soluzione — crea il formattatore una volta per l'intero schermo e riutilizzalo. Per l'accesso multi-thread, utilizza la sincronizzazione tramite DispatchQueue.

swift
import Foundation

// DateFormatter in cache — creato una volta
private let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "dd.MM.yyyy HH:mm"
    formatter.locale = Locale(identifier: "ru_RU")
    formatter.timeZone = TimeZone(identifier: "Europe/Moscow")
    return formatter
}()

// ISO8601DateFormatter — alternativa leggera
private let isoFormatter: ISO8601DateFormatter = {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
    return formatter
}()

let now = Date()
let formattedDate = dateFormatter.string(from: now)
// "01.07.2026 14:30"
let isoDate = isoFormatter.string(from: now)
// "2026-07-01T14:30:00.000Z"

Per il formato ISO 8601, utilizza ISO8601DateFormatter — non richiede la specifica di un pattern e funziona più velocemente di DateFormatter. Su iOS 10+, questa classe è preferibile per lavorare con le date del server. Per i vecchi formati, mantieni DateFormatter ma assicurati di mantenere in cache l'istanza come proprietà statica o singleton.

Data e ora su Android: java.time e DateTimeFormatter

Su Android, data e ora vengono gestite tramite il pacchetto java.time, disponibile dall'API 26. Classi principali: LocalDate (solo data), LocalTime (solo ora), LocalDateTime (data e ora senza fuso orario) e ZonedDateTime (con fuso orario). DateTimeFormatter — un formattatore thread-safe per la piattaforma mobile Android. La data nelle applicazioni mobili viene formattata tramite DateTimeFormatter e LocalDate senza perdita di prestazioni.

LocalDate, ZonedDateTime e formattazione

LocalDate archivia la data senza ora — ideale per i compleanni. ZonedDateTime archivia le informazioni complete con fuso orario. DateTimeFormatter supporta pattern predefiniti (ISO_LOCAL_DATE, ISO_DATE_TIME) e personalizzati tramite ofPattern. Tutte le classi java.time sono immutabili e thread-safe, eliminando le race condition quando si lavora in più thread.

kotlin
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.ZoneId

// Creare e formattare la data corrente
val today = LocalDate.now()
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
val formatted = today.format(formatter)

// Lavorare con i fusi orari
val utcTime = ZonedDateTime.now(ZoneId.of("UTC"))
val moscowTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/Moscow"))

DateTimeFormatter è significativamente più performante di SimpleDateFormat perché non analizza il pattern a ogni chiamata. Si consiglia di creare costanti di formattatore a livello di classe o oggetto companion. Per convertire un Unix Timestamp, utilizza Instant.ofEpochSecond, poi converti in LocalDateTime o ZonedDateTime tramite il fuso orario.

Fusi orari: data e ora nelle applicazioni mobili e TimeZone

La data e ora corretta sullo schermo dell'utente dipende dalla corretta gestione dei fusi orari. Data e ora nello sviluppo mobile per Android richiede la considerazione del fuso orario del dispositivo. La regola d'oro: archivia l'ora in UTC, converti nel fuso orario locale solo per la visualizzazione. iOS fornisce TimeZone da Foundation, Android fornisce ZoneId da java.time. Entrambe le API per piattaforme mobili supportano il rilevamento automatico del fuso orario corrente del dispositivo. La data in un'applicazione mobile dipende da ZoneId e TimeZone.

Ora legale e identificatori IANA

L'ora legale crea ambiguità: un momento nel tempo può essere rappresentato da due ore locali diverse. java.time e Foundation gestiscono automaticamente l'ora legale. Utilizza identificatori IANA (Europe/Moscow, America/New_York), non abbreviazioni (MSK, EST) — le abbreviazioni sono ambigue e ignorano il passaggio all'ora legale.

swift
import Foundation

// Convertire UTC in ora locale su iOS
func formatToLocalTime(utcDate: Date, timeZoneId: String) -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "dd.MM.yyyy HH:mm"
    formatter.timeZone = TimeZone(identifier: timeZoneId)
    return formatter.string(from: utcDate)
}

// Determinare il fuso orario del dispositivo
let localTimeZone = TimeZone.current
let isDST = localTimeZone.isDaylightSavingTime()
let secondsFromGMT = localTimeZone.secondsFromGMT()

Su Android, utilizza ZoneId.systemDefault() per ottenere il fuso orario del dispositivo. Quando converti UTC in ora locale, crea un ZonedDateTime con ZoneOffset.UTC e applica withZoneSameInstant. Per le vecchie API senza java.time, utilizza TimeZone.getDefault() e Calendar — ma è meglio aggiungere direttamente ThreeTenABP.

kotlin
import java.time.Instant
import java.time.ZonedDateTime
import java.time.ZoneId

// Convertire Unix Timestamp in ora locale
fun toLocalDisplay(unixSeconds: Long): String {
    val instant = Instant.ofEpochSecond(unixSeconds)
    val local = instant.atZone(ZoneId.systemDefault())
    return local.format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"))
}

ThreeTenABP — data e ora per vecchie versioni di Android

ThreeTenABP — una libreria adattatrice che porta java.time su Android API inferiore a 26. Fornisce le stesse classi: LocalDate, LocalTime, ZonedDateTime, DateTimeFormatter, Instant. Se l'applicazione supporta Android 5 o 6 (API 21-25), ThreeTenABP è l'unico modo per utilizzare un'API mobile moderna senza migrare al deprecato Calendar. Data e ora nello sviluppo mobile per dispositivi vecchi è implementata tramite questa libreria. Per i dispositivi vecchi, data e ora sono implementate tramite ThreeTenABP.

Aggiunta e configurazione di ThreeTenABP

La libreria richiede l'inizializzazione nel metodo Application.onCreate() chiamando AndroidThreeTen.init(). Questo carica i dati dei fusi orari dagli assets. Dopo l'inizializzazione, l'API è totalmente identica a java.time — il codice per API 26+ e per API 21+ sarà lo stesso. La dimensione della libreria è di circa 400 KB, accettabile per la maggior parte delle applicazioni mobili.

kotlin
import org.threeten.bp.LocalDate
import org.threeten.bp.format.DateTimeFormatter

// Inizializzazione in Application
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}

// API è identica a java.time
val today = LocalDate.now()
val formatted = today.format(DateTimeFormatter.ISO_LOCAL_DATE)

Le prestazioni di ThreeTenABP sono paragonabili a java.time originale sui dispositivi moderni. Sui dispositivi vecchi, potrebbe esserci un ritardo alla prima chiamata a causa del caricamento dei dati dei fusi orari. Migra il codice esistente da Calendar a ThreeTenABP gradualmente: sostituisci Date e Calendar con Instant e LocalDate nei nuovi moduli, lasciando il vecchio codice invariato.

Unix Timestamp e sincronizzazione dell'ora via NTP

Unix Timestamp — il numero di secondi trascorsi dal 1° gennaio 1970 00:00 UTC. Questo è un formato universale per archiviare e scambiare il tempo tra server e client. Tuttavia, l'ora sul dispositivo può differire dall'ora reale a causa delle impostazioni dell'utente. Per la sincronizzazione viene utilizzato NTP — un protocollo di tempo preciso via UDP. Unix Timestamp è il formato in cui data e ora vengono archiviate sul server.

Ottenere Unix Timestamp e sincronizzazione NTP

Date().timeIntervalSince1970 su iOS restituisce secondi dal 1970. Su Android, System.currentTimeMillis() restituisce millisecondi. Per la precisione, utilizza NTP: la libreria TrueTime per iOS e AndroidNtp per Android inviano una richiesta a un server NTP e calcolano lo scostamento orario. La precisione di NTP è di 1-10 ms su rete locale e 10-100 ms via internet.

swift
import Foundation

// Ottenere Unix Timestamp su iOS
let seconds = Date().timeIntervalSince1970
let milliseconds = Int64(seconds * 1000)

// Sincronizzazione NTP con TrueTime
TrueTime.shared.start { result in
    switch result {
    case .success:
        let ntpTime = TrueTime.shared.now()
        print("Ora esatta: \(ntpTime)")
    case .failure(let error):
        print("Errore NTP: \(error)")
    }
}

Senza sincronizzazione in un'applicazione mobile, sono possibili errori: timestamp di eventi errati, desincronizzazione con il server. Il tempo nello sviluppo mobile viene sincronizzato via NTP una volta all'avvio dell'applicazione, dopo di che viene utilizzato lo scostamento calcolato. Per le applicazioni mobili critiche in termini di precisione (finanza, logistica), il protocollo NTP è obbligatorio prima di inviare i dati al server.

Domande frequenti

Perché DateFormatter è lento su iOS?

DateFormatter analizza il pattern di formattazione, carica la locale e determina il fuso orario ogni volta che viene creata un'istanza. Mantieni in cache il formattatore come costante statica o utilizza ISO8601DateFormatter per ISO 8601 — è più leggero e veloce.

Cosa usare al posto di SimpleDateFormat su Android?

DateTimeFormatter dal pacchetto java.time — thread-safe e performante. Disponibile dall'API 26. Per le vecchie versioni, utilizza ThreeTenABP che fornisce un'API identica.

Come lavorare con date precedenti a Java 8 su Android?

Aggiungi ThreeTenABP — un backport di java.time per Android API 21+. Inizializza tramite AndroidThreeTen.init() in Application.onCreate(). L'API è totalmente identica a java.time originale.

È necessario archiviare l'ora in UTC?

Sì, archivia l'ora in UTC sul server e nel database locale. Converti nel fuso orario locale dell'utente solo nella fase di visualizzazione. Questo elimina gli errori al cambio di fuso orario o durante i viaggi.

Come ottenere Unix Timestamp su iOS?

Date().timeIntervalSince1970 restituisce il numero di secondi dal 1° gennaio 1970. Per i millisecondi, moltiplica per 1000 e converti in Int64. Per una sincronizzazione precisa, utilizza la libreria TrueTime con un server NTP.

Riepilogo

  • DateFormatter su iOS — lo strumento principale per formattare data e ora, richiede la memorizzazione nella cache obbligatoria delle istanze. ISO8601DateFormatter è un'alternativa più leggera per ISO 8601.
  • DateTimeFormatter su Android — formattatore thread-safe di java.time per API 26+. LocalDate e ZonedDateTime sono le classi principali per lavorare con le date.
  • ThreeTenABP — un'API unificata per tutte le versioni di Android. Aggiungi per la retrocompatibilità con API 21-25. Il codice non differisce da java.time.
  • TimeZone e UTC — archivia l'ora in UTC, converti nel fuso orario locale solo per la visualizzazione. Utilizza identificatori IANA.
  • Unix Timestamp — un formato universale per lo scambio di tempo tra server e client. Ottienilo tramite Date().timeIntervalSince1970 su iOS.
  • Sincronizzazione NTP — garantisce precisione temporale al millisecondo. TrueTime (iOS) e AndroidNtp (Android) sono le librerie standard.

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