Duration — cos’è, calcolare la durata in Android

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

Duration — una classe immutabile del pacchetto java.time che rappresenta la durata tra due momenti nel tempo in secondi e nanosecondi. Duration misura quantità di tempo basate sul tempo — ore, minuti, secondi, millisecondi e nanosecondi. Secondo le specifiche di Oracle Java 17 (2024), a differenza di Period (che misura anni-mesi-giorni), Duration lavora con unità di tempo precise e non dipende dal calendario.

Punti chiave

  • Duration — una classe immutabile per misurare la durata in secondi e nanosecondi.
  • A differenza di Period, Duration lavora con unità basate sul tempo (ore, minuti, secondi), non basate sulla data (giorni, mesi, anni).
  • Creata tramite Duration.between(start, end), Duration.ofMinutes(), Duration.ofHours() e altri metodi factory statici.
  • Supporta operazioni aritmetiche: plus(), minus(), multipliedBy(), dividedBy(), negated().
  • Per lo sviluppo Android, Duration è utile per calcolare timeout, intervalli di sincronizzazione e durata delle operazioni.

Cos’è Duration?

Duration è una classe che modella la quantità di tempo in secondi e nanosecondi. Rappresenta una durata basata sul tempo, ovvero un numero fisico di secondi non legato a un calendario. Duration può essere pensata come “125 minuti” o “2 ore 5 minuti” — a differenza di Period, che direbbe “2 mesi”.

La rappresentazione interna di Duration consiste in due campi: long seconds (secondi) e int nanos (nanosecondi, da 0 a 999999999). Il valore può essere negativo — significa una durata “all’indietro” nel tempo. Il valore massimo è ±31557014167219200 secondi.

Secondo Baeldung (2024), Duration è una classe chiave per calcolare la durata delle operazioni, impostare timeout e misurare le prestazioni. Duration è immutabile e thread-safe, consentendone l’uso in ambienti multithread senza sincronizzazione.

La classe implementa le interfacce Comparable, TemporalAmount e TemporalUnit. TemporalAmount permette di utilizzare Duration nei metodi plus/minus delle classi LocalTime, LocalDateTime, Instant e ZonedDateTime.

Duration vs Period: qual è la differenza?

La differenza principale è che Duration misura il numero esatto di secondi (basato sul tempo), mentre Period misura unità di calendario (basate sulla data): anni, mesi, giorni. Duration dice: “86400 secondi sono passati.” Period dice: “1 giorno è passato.” La differenza diventa evidente durante i cambi dell’ora legale — 1 giorno in Period è sempre 1 giorno di calendario, mentre 86400 secondi in Duration possono corrispondere a 23 o 25 ore durante il DST.

Duration viene utilizzata per misurare il tempo fisico: timeout di connessione, tempo di esecuzione delle query, intervalli tra due Instant. Period viene utilizzata per calcoli di calendario: età di una persona (Period.between(dateOfBirth, today)), durata di un contratto.

Duration lavora con secondi e nanosecondi, quindi può essere suddivisa in parti (ore, minuti). Period lavora con anni, mesi e giorni — unità di calendario indivisibili. Secondo Oracle Java Tutorial (2024), la scelta tra Duration e Period dipende dal tipo di attività: tempo preciso vs date di calendario.

Creare Duration

Il metodo più comune è Duration.between(Temporal start, Temporal end). Temporal può essere Instant, LocalTime, LocalDateTime, ZonedDateTime — qualsiasi tipo che implementi Temporal. Il metodo restituisce una Duration che rappresenta la differenza start - end (può essere negativa).

Metodi factory statici: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Esiste anche of(long amount, TemporalUnit unit) per unità arbitrarie — ChronoUnit.HOURS, ChronoUnit.MINUTES e altre.

Il metodo parse(CharSequence) accetta una stringa in formato ISO-8601: “PT1H30M” (1 ora 30 minuti), “PT45S” (45 secondi), “P2DT3H” (2 giorni 3 ore). La stringa inizia sempre con “PT” (Period of Time).

kotlin
val betweenMoments = Duration.between(
    Instant.parse("2026-07-21T10:00:00Z"),
    Instant.parse("2026-07-21T14:30:00Z")
)

val fromMinutes = Duration.ofMinutes(90)
val fromHours = Duration.ofHours(2)
val parsed = Duration.parse("PT1H30M")

Aritmetica con Duration

Duration supporta un set completo di operazioni aritmetiche. I metodi plus(Duration) e minus(Duration) aggiungono o sottraggono un’altra durata. I metodi plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() — per aggiungere unità specifiche.

Per moltiplicazione e divisione, usa multipliedBy(long) e dividedBy(long). Duration.multipliedBy(2) raddoppia la durata. Duration.dividedBy(3) divide in tre parti con arrotondamento per difetto. Il metodo negated() inverte il segno — il positivo diventa negativo e viceversa.

Il metodo abs() restituisce una Duration con valore assoluto (positivo). isNegative() e isZero() sono controlli. toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() convertono nelle unità corrispondenti.

kotlin
val oneHour = Duration.ofHours(1)
val twoHours = oneHour.plus(Duration.ofMinutes(60))
val halfHour = oneHour.dividedBy(2)

val minutes = twoHours.toMinutes()
val absDuration = (Duration.ofHours(-1)).abs()

Confrontare Duration

Duration implementa l’interfaccia Comparable, consentendo di confrontare le durate naturalmente. Il metodo compareTo() restituisce un numero negativo, zero o positivo. isNegative() e isZero() sono controlli rapidi. Per un confronto esplicito, usa equals() — due Duration sono uguali se i loro secondi e nanosecondi coincidono.

Poiché Duration può essere negativa, i confronti “maggiore di” o “minore di” funzionano considerando il segno. -5 minuti è minore di 2 minuti. Il metodo abs() è utile per confrontare lunghezze “assolute” indipendentemente dalla direzione.

In Kotlin, Duration supporta gli operatori di confronto tramite l’overloading degli operatori: a < b, a > b, a <= b. Plus e minus sono disponibili anche come operatori: a + b, a - b.

kotlin
val short = Duration.ofMinutes(5)
val long = Duration.ofMinutes(10)

if (short < long) {
    Log.d("Duration", "5 min è meno di 10")
}

val negative = Duration.ofMinutes(-3)
Log.d("Duration", "Negativo: ${negative.isNegative()}")

Duration nei compiti Android reali

Il primo esempio è la configurazione della sincronizzazione periodica con il server. Duration viene utilizzata per calcolare l’intervallo tra le sincronizzazioni e verificare se il limite di tempo senza aggiornamento è stato superato.

kotlin
data class SyncConfig(
    val interval: Duration = Duration.ofMinutes(15),
    val retryDelay: Duration = Duration.ofSeconds(30)
)

fun calculateNextSync(
    lastSync: Instant,
    config: SyncConfig
): Duration {
    val elapsed = Duration.between(lastSync, Instant.now())
    return config.interval.minus(elapsed)
        .coerceAtLeast(Duration.ZERO)
}

Il secondo esempio è la misurazione del tempo di esecuzione di un’operazione per la registrazione delle prestazioni.

kotlin
fun measureExecution(
    tag: String,
    block: () -> Unit
) {
    val start = Instant.now()
    block()
    val duration = Duration.between(start, Instant.now())
    Log.d(tag, "Eseguito in ${duration.toMillis()} ms")
}

Il terzo esempio è il calcolo del tempo rimanente di un timer (ad esempio, il conto alla rovescia fino alla fine di una promozione).

kotlin
class CountdownTimer(
    private val expiresAt: Instant
) {
    fun getRemainingTime(): Duration {
        val remaining = Duration.between(
            Instant.now(), expiresAt
        )
        return remaining.coerceAtLeast(Duration.ZERO)
    }

    fun isExpired(): Boolean = getRemainingTime() == Duration.ZERO
}

Convertire Duration in stringa

Il metodo toString() restituisce Duration in formato ISO-8601: “PT1H30M” (1 ora 30 minuti), “PT45.5S” (45.5 secondi). Questo formato è comodo per lo scambio tra macchine ma non per la visualizzazione all’utente.

Per un formato leggibile dall’uomo, usa toDays(), toHours(), toMinutes(), toSeconds() seguiti dalla costruzione manuale della stringa. Ad esempio: “${days} g ${hours} h ${minutes} min”. Nota che toHours() restituisce il numero totale di ore, non le ore all’interno del giorno.

Per scomporre Duration in componenti, usa la formula: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. Secondo Apache Commons Lang (2024), la libreria DurationFormatUtils fornisce capacità di formattazione aggiuntive.

kotlin
fun formatDuration(duration: Duration): String {
    val hours = duration.toHours()
    val minutes = duration.toMinutes() % 60
    val seconds = duration.seconds % 60

    return buildString {
        if (hours > 0) append("${hours} h ")
        if (minutes > 0) append("${minutes} min ")
        append("${seconds} sec")
    }
}

Errori comuni

Il primo errore è confondere Duration e Period quando si lavora con le date. Duration misura secondi, quindi Duration.ofDays(1) è sempre 24 ore (86400 secondi), indipendentemente dai cambi dell’ora legale. Se hai bisogno di un giorno di calendario, usa Period.ofDays(1).

Il secondo errore è la perdita di nanosecondi durante la conversione. Duration può memorizzare nanosecondi, ma toMillis() e toSeconds() li scartano. Per calcoli precisi, usa toNanos() o lavora direttamente con Duration senza convertire in primitivi.

Il terzo errore è ignorare Duration negative. Duration.between(start, end) restituisce start - end. Se start è dopo end, Duration sarà negativa. Il metodo abs() aiuta a ottenere il valore assoluto e isNegative() verifica l’ordine degli argomenti.

Il quarto errore è una formattazione errata di Duration per l’interfaccia utente. Duration.toString() restituisce ISO-8601, che non è leggibile. Formatta sempre Duration manualmente per la visualizzazione all’utente usando toHours(), toMinutes() e toSeconds() con il resto corretto della divisione.

Domande frequenti

Duration può essere negativa?

Sì, Duration può essere negativa. Duration.between(start, end) restituisce start - end. Se start è dopo end, Duration sarà negativa. Usa abs() per ottenere il valore assoluto o isNegative() per verificare.

Come sommare due Duration?

Usa il metodo plus(Duration) o l’operatore + in Kotlin: duration1 + duration2. Il risultato è una nuova Duration. Il metodo minus(Duration) sottrae una durata da un’altra. Tutte le operazioni sono immutabili e restituiscono un nuovo oggetto.

In che modo Duration.ofDays(1) differisce da Period.ofDays(1)?

Duration.ofDays(1) è sempre 24 ore (86400 secondi). Period.ofDays(1) è 1 giorno di calendario, che durante il DST può essere 23 o 25 ore. Per calcoli di tempo precisi, usa Duration; per calcoli di calendario, usa Period.

Come convertire Duration in millisecondi?

Usa il metodo toMillis(). Restituisce un long — il numero di millisecondi nella Duration. Per i nanosecondi, usa toNanos(). Attenzione: toNanos() può far overfloware long per valori > 292 anni. Per Duration grandi, usa toSeconds() o toMinutes().

Come calcolare Duration tra due LocalTime?

Usa Duration.between(startTime, endTime). Se endTime è minore di startTime (turno notturno), Duration sarà negativa. Aggiungi 24 ore: duration.plusHours(24), se si presume che endTime sia il giorno successivo.

Riepilogo

  • Duration — una classe immutabile per la durata basata sul tempo con precisione al nanosecondo, ideale per misurare intervalli.
  • La differenza principale da Period — Duration misura secondi (tempo fisico), Period misura unità di calendario.
  • Creata tramite Duration.between() per la differenza tra momenti o tramite factory statici ofMinutes, ofHours, ofDays.
  • Supporta l’aritmetica: plus, minus, multipliedBy, dividedBy, nonché il confronto tramite Comparable e abs.
  • In Android, Duration viene utilizzata per calcolare timeout, intervalli di sincronizzazione, timer e misurazione delle prestazioni.
  • Quando si visualizza all’utente, formatta Duration manualmente — toString() restituisce ISO-8601, non leggibile dall’uomo.
  • Tieni presente che Duration può essere negativa — controlla isNegative() e usa abs() per calcoli corretti.

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