Duration — ce este, calcularea duratei în Android

Autor: IT Sectr Publicat: 2026-07-13 Timp de citire: 9 min

Duration — clasĄ imuabilĄ din pachetul java.time, care reprezintĄ durata dintre două momente de timp în secunde și nanosecunde. Duration măsoară cantitatea de timp bazată pe timp — ore, minute, secunde, milisecunde și nanosecunde. Conform specificației Oracle Java 17 (2024), spre deosebire de Period (care măsoară ani-luni-zile), Duration lucrează cu unități exacte de timp și nu depinde de calendar.

Principalele puncte

  • Duration — clasĄ imuabilĄ pentru măsurarea duratei în secunde și nanosecunde.
  • Spre deosebire de Period, Duration lucrează cu unități bazate pe timp (ore, minute, secunde), nu pe dată (zile, luni, ani).
  • Se creeazĄ prin Duration.between(start, end), Duration.ofMinutes(), Duration.ofHours() și alte fabrici statice.
  • Suportă operații aritmetice: plus(), minus(), multipliedBy(), dividedBy(), negated().
  • Pentru dezvoltarea Android, Duration este util pentru calcularea timeout-urilor, intervalelor de sincronizare și duratei operațiilor.

Ce este Duration?

Duration — este o clasă care modelează cantitatea de timp în secunde și nanosecunde. Reprezintă durata bazată pe timp, adică numărul fizic de secunde, nelegat de calendar. Duration poate fi reprezentat ca „125 de minute” sau „2 ore și 5 minute” — spre deosebire de Period, care va spune „2 luni”.

Reprezentarea internĄ a Duration constă din două câmpuri: long seconds (secunde) și int nanos (nanosecunde, de la 0 la 999999999). Valoarea poate fi negativă — aceasta înseamnă durata „înapoi” în timp. Valoarea maximă este ±31557014167219200 secunde.

Conform Baeldung (2024), Duration este clasa cheie pentru calcularea duratei operațiilor, setarea timeout-urilor și măsurarea performanței. Duration este imuabilă și thread-safe, ceea ce permite utilizarea sa în medii multi-thread fără sincronizare.

Clasa implementează interfețele Comparable, TemporalAmount și TemporalUnit. TemporalAmount permite utilizarea Duration în metodele plus/minus ale claselor LocalTime, LocalDateTime, Instant și ZonedDateTime.

Duration vs Period: care este diferența?

Diferența principală — Duration măsoară numărul exact de secunde (time-based), iar Period măsoară unitățile calendaristice (date-based): ani, luni, zile. Duration spune: „au trecut 86400 de secunde”. Period spune: „a trecut 1 zi”. Diferența se manifestă la trecerea la ora de vară — 1 zi în Period este întotdeauna egală cu 1 zi în calendar, iar 86400 de secunde în Duration pot corespunde la 23 sau 25 de ore în DST.

Duration este folosită pentru măsurarea timpului fizic: timeout-uri de conexiune, timpul de execuție a cererii, intervalul dintre două Instant. Period este folosită pentru calcule calendaristice: vârsta unei persoane (Period.between(dataNașterii, azi)), perioada de valabilitate a contractului.

Duration lucrează cu secunde și nanosecunde, deci poate fi împărțită în părți (ore, minute). Period lucrează cu ani, luni și zile — unități calendaristice indivizibile. Conform Oracle Java Tutorial (2024), alegerea între Duration și Period depinde de tipul sarcinii: timp exact vs date calendaristice.

Crearea Duration

Cel mai frecvent mod — Duration.between(Temporal start, Temporal end). Temporal poate fi Instant, LocalTime, LocalDateTime, ZonedDateTime — orice tip care implementează Temporal. Metoda returnează o Duration reprezentând diferența start - end (poate fi negativă).

Metode de fabrică statice: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Există și of(long amount, TemporalUnit unit) pentru unități arbitrare — ChronoUnit.HOURS, ChronoUnit.MINUTES și altele.

Metoda parse(CharSequence) acceptă un șir în format ISO-8601: „PT1H30M” (1 oră 30 minute), „PT45S” (45 secunde), „P2DT3H” (2 zile 3 ore). Șirul începe întotdeauna cu „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 cu Duration

Duration suportă un set complet de operații aritmetice. Metodele plus(Duration) și minus(Duration) adaugă sau scad o altă durată. Metodele plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() — pentru adăugarea precisă a unităților.

Pentru înmulțire și împărțire se folosesc multipliedBy(long) și dividedBy(long). Duration.multipliedBy(2) dublează durata. Duration.dividedBy(3) împarte în trei părți cu rotunjire în jos. Metoda negated() inversează semnul — pozitivă devine negativă și invers.

Metoda abs() returnează Duration cu valoarea absolută (pozitivă). isNegative() și isZero() — verificări. toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() — conversia în unitățile corespunzătoare.

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()

Compararea Duration

Duration implementează interfața Comparable, ceea ce permite compararea naturală a duratelor. Metoda compareTo() returnează un număr negativ, zero sau pozitiv. Metodele isNegative() și isZero() — verificări rapide. Pentru comparare explicită folosiți equals() — două Duration sunt egale dacă au aceleași secunde și nanosecunde.

Deoarece Duration poate fi negativă, compararea „mai mare” sau „mai mic” funcționează ținând cont de semn. -5 minute este mai mic decât 2 minute. Metoda abs() este utilă dacă trebuie să comparați lungimi „absolute” independent de direcție.

În Kotlin, Duration suportă operatorii de comparare prin supraîncărcarea operatorilor: a < b, a > b, a <= b. De asemenea, plus și minus sunt disponibili ca operatori: a + b, a - b.

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

if (short < long) {
    Log.d("Duration", "5 min este mai puțin de 10")
}

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

Duration în sarcinile reale Android

Primul exemplu — configurarea sincronizării periodice cu serverul. Duration este folosită pentru calcularea intervalului între sincronizări și verificarea dacă limita de timp fără actualizare a fost depășită.

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)
}

Al doilea exemplu — măsurarea timpului de execuție a operației pentru logarea performanței.

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

Al treilea exemplu — calcularea timpului rămas al timer-ului (de exemplu, pentru numărătoarea inversă până la sfârșitul unei promoții).

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
}

Conversia Duration în șir

Metoda toString() returnează Duration în format ISO-8601: „PT1H30M” (1 oră 30 minute), „PT45.5S” (45.5 secunde). Acest format este convenabil pentru schimbul mașină-mașină, dar nu pentru afișarea utilizatorului.

Pentru un format lizibil de către om, folosiți toDays(), toHours(), toMinutes(), toSeconds() cu construirea manuală a șirului. De exemplu: „${days} z ${hours} h ${minutes} min”. Rețineți că toHours() returnează numărul total de ore, nu orele din zi.

Pentru descompunerea Duration în componente se folosește formula: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. Conform Apache Commons Lang (2024), biblioteca DurationFormatUtils oferă capacități suplimentare de formatare.

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")
    }
}

Erori tipice

Prima eroare — confuzia între Duration și Period la lucrul cu datele. Duration măsoară secunde, deci Duration.ofDays(1) este întotdeauna 24 de ore (86400 secunde), indiferent de trecerea la ora de vară. Dacă aveți nevoie de o zi calendaristică, folosiți Period.ofDays(1).

A doua eroare — pierderea nanosecundelor la conversie. Duration poate stoca nanosecunde, dar toMillis() și toSeconds() le elimină. Pentru calcule precise, folosiți toNanos() sau lucrați direct cu Duration, fără conversie în tipuri primitive.

A treia eroare — ignorarea Duration negative. Duration.between(start, end) returnează start - end. Dacă start este după end, Duration va fi negativă. Metoda abs() ajută la obținerea valorii absolute, iar isNegative() — la verificarea ordinii argumentelor.

A patra eroare — formatarea incorectă a Duration pentru UI. Duration.toString() returnează ISO-8601, care este ilizibil. Formatați întotdeauna Duration manual pentru afișarea utilizatorului, folosind toHours(), toMinutes() și toSeconds() cu restul corect al împărțirii.

Întrebări frecvente

Poate Duration să fie negativă?

Da, Duration poate fi negativă. Duration.between(start, end) returnează start - end. Dacă start este după end, Duration va fi negativă. Folosiți abs() pentru a obține valoarea absolută sau isNegative() pentru verificare.

Cum să adun două Duration?

Folosiți metoda plus(Duration) sau operatorul + în Kotlin: duration1 + duration2. Rezultatul — o nouă Duration. Metoda minus(Duration) scade o durată din alta. Toate operațiile sunt imuabile și returnează un obiect nou.

Cu ce diferă Duration.ofDays(1) de Period.ofDays(1)?

Duration.ofDays(1) este întotdeauna 24 de ore (86400 secunde). Period.ofDays(1) este 1 zi calendaristică, care în DST poate fi de 23 sau 25 de ore. Pentru calcule cu timp exact folosiți Duration, pentru cele calendaristice — Period.

Cum să convertesc Duration în milisecunde?

Folosiți metoda toMillis(). Returnează un long — numărul de milisecunde în Duration. Pentru nanosecunde folosiți toNanos(). Atenție: toNanos() poate depăși domeniul long la valori > 292 de ani. Pentru Duration mari folosiți toSeconds() sau toMinutes().

Cum să calculez Duration între două LocalTime?

Folosiți Duration.between(startTime, endTime). Dacă endTime este mai mic decât startTime (tura de noapte), Duration va fi negativă. Adăugați 24 de ore: duration.plusHours(24), dacă presupuneți că endTime este ziua următoare.

Rezumat

  • Duration — clasĄ imuabilĄ pentru durata bazată pe timp cu precizie de nanosecunde, ideală pentru măsurarea intervalelor.
  • Diferența principală de Period — Duration măsoară secunde (timp fizic), Period — unități calendaristice.
  • Se creează prin Duration.between() pentru diferența dintre momente sau prin fabricile statice ofMinutes, ofHours, ofDays.
  • Suportă aritmetică: plus, minus, multipliedBy, dividedBy, precum și comparare prin Comparable și abs.
  • În Android, Duration este folosită pentru calcularea timeout-urilor, intervalelor de sincronizare, timerelor și măsurării performanței.
  • La afișarea utilizatorului, formatați Duration manual — toString() returnează ISO-8601, ilizibil pentru om.
  • Rețineți că Duration poate fi negativă — verificați isNegative() și folosiți abs() pentru calcule corecte.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și