Duration — megváltoztathatatlan osztály a java.time csomagból, amely két időpillanat közötti időtartamot reprezentál másodpercekben és nanoszekundumokban. A Duration időalapú időmennyiséget mér — órákat, perceket, másodperceket, ezredmásodperceket és nanoszekundumokat. A Oracle Java 17 (2024) specifikáció szerint, ellentétben a Period-dal (amely éveket-hónapokat-napokat mér), a Duration pontos időegységekkel dolgozik és nem függ a naptártól.
Főbb pontok
Duration — egy osztály, amely az idő mennyiségét modellezi másodpercekben és nanoszekundumokban. Időalapú időtartamot reprezentál, azaz a másodpercek fizikai számát, amely nem kötődik naptárhoz. A Duration ábrázolható „125 perc” vagy „2 óra 5 perc” ként — ellentétben a Period-dal, amely „2 hónap”-ot mond.
A Duration belső reprezentációja két mezőből áll: long seconds (másodpercek) és int nanos (nanoszekundumok, 0-tól 999999999-ig). Az érték lehet negatív — ez „visszafelé” időtartamot jelent. A maximális érték ±31557014167219200 másodperc.
A Baeldung (2024) szerint a Duration a kulcsfontosságú osztály a műveletek időtartamának kiszámításához, időtúllépések beállításához és teljesítmény méréséhez. A Duration megváltoztathatatlan és szálszinkronizált, ami lehetővé teszi használatát többszálas környezetben szinkronizáció nélkül.
Az osztály implementálja a Comparable, TemporalAmount és TemporalUnit interfészeket. A TemporalAmount lehetővé teszi a Duration használatát a LocalTime, LocalDateTime, Instant és ZonedDateTime osztályok plus/minus metódusaiban.
A fő különbség — Duration a másodpercek pontos számát méri (time-based), míg Period a naptári egységeket (date-based): évek, hónapok, napok. A Duration azt mondja: „86400 másodperc telt el”. A Period azt mondja: „1 nap telt el”. A különbség a nyári időszámításra váltáskor mutatkozik meg — 1 nap a Period-ban mindig egyenlő 1 nappal a naptárban, míg 86400 másodperc a Duration-ban 23 vagy 25 órának felelhet meg DST esetén.
A Duration a fizikai idő mérésére szolgál: kapcsolati időtúllépések, kérés végrehajtási ideje, két Instant közötti intervallum. A Period naptári számításokra szolgál: személy életkora (Period.between(születésiDátum, ma)), szerződés érvényességi ideje.
A Duration másodpercekkel és nanoszekundumokkal dolgozik, így részekre osztható (órák, percek). A Period évekkel, hónapokkal és napokkal dolgozik — oszthatatlan naptári egységek. A Oracle Java Tutorial (2024) szerint a Duration és Period közötti választás a feladat típusától függ: pontos idő vs naptári dátumok.
A leggyakoribb mód — Duration.between(Temporal start, Temporal end). A Temporal lehet Instant, LocalTime, LocalDateTime, ZonedDateTime — bármely típus, amely implementálja a Temporal-t. A metódus egy Duration-t ad vissza, amely a start - end különbséget reprezentálja (lehet negatív).
Statikus gyári metódusok: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Létezik of(long amount, TemporalUnit unit) is tetszőleges egységekhez — ChronoUnit.HOURS, ChronoUnit.MINUTES és mások.
A parse(CharSequence) metódus ISO-8601 formátumú szöveget fogad: „PT1H30M” (1 óra 30 perc), „PT45S” (45 másodperc), „P2DT3H” (2 nap 3 óra). A szöveg mindig „PT”-vel (Period of Time) kezdődik.
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")
A Duration teljes aritmetikai műveletkészletet támogat. A plus(Duration) és minus(Duration) metódusok hozzáadnak vagy kivonnak egy másik időtartamot. A plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() metódusok — egységek pontos hozzáadásához.
Szorzáshoz és osztáshoz a multipliedBy(long) és dividedBy(long) használható. A Duration.multipliedBy(2) megkétszerezi az időtartamot. A Duration.dividedBy(3) három részre osztja lefelé kerekítéssel. A negated() metódus megfordítja az előjelet — a pozitív negatívvá válik és fordítva.
Az abs() metódus egy Duration-t ad vissza abszolút (pozitív) értékkel. Az isNegative() és isZero() — ellenőrzések. A toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() — konverzió a megfelelő egységekbe.
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()
A Duration implementálja a Comparable interfészt, ami lehetővé teszi az időtartamok természetes összehasonlítását. A compareTo() metódus negatív számot, nullát vagy pozitív számot ad vissza. Az isNegative() és isZero() metódusok — gyors ellenőrzések. Explicite összehasonlításhoz használja az equals()-t — két Duration egyenlő, ha ugyanazok a másodperceik és nanoszekundumaik.
Mivel a Duration lehet negatív, a „nagyobb” vagy „kisebb” összehasonlítás az előjel figyelembevételével működik. -5 perc kisebb, mint 2 perc. Az abs() metódus akkor hasznos, ha „abszolút” hosszakat kell összehasonlítani irányól függetlenül.
Kotlinban a Duration támogatja az összehasonlító operátorokat operátor túlterheléssel: a < b, a > b, a <= b. A plus és minus is elérhető operátorként: a + b, a - b.
val short = Duration.ofMinutes(5)
val long = Duration.ofMinutes(10)
if (short < long) {
Log.d("Duration", "5 perc kevesebb, mint 10")
}
val negative = Duration.ofMinutes(-3)
Log.d("Duration", "Negatív: ${negative.isNegative()}")
Az első példa — periódusos szinkronizáció beállítása a szerverrel. Duration használatos a szinkronizációk közötti intervallum kiszámítására és annak ellenőrzésére, hogy a frissítés nélküli időkorlát túllépésre került-e.
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)
}
A második példa — egy művelet végrehajtási idejének mérése teljesítménynaplózáshoz.
fun measureExecution(
tag: String,
block: () -> Unit
) {
val start = Instant.now()
block()
val duration = Duration.between(start, Instant.now())
Log.d(tag, "Végrehajtva ${duration.toMillis()} ms alatt")
}
A harmadik példa — az időzítő hátralevő idejének kiszámítása (például visszasámlálás egy akció végéig).
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
}
A toString() metódus a Duration-t ISO-8601 formátumban adja vissza: „PT1H30M” (1 óra 30 perc), „PT45.5S” (45.5 másodperc). Ez a formátum kényelmes gépi cseréhez, de nem felhasználói megjelenítésre.
Ember által olvasható formátumhoz használja a toDays(), toHours(), toMinutes(), toSeconds() metódusokat kézi szövegösszeállítással. Például: „${days} n ${hours} ó ${minutes} p”. Vegye figyelembe, hogy a toHours() az órák teljes számát adja vissza, nem az órákat egy napon belül.
A Duration összetevőkre bontásához a képlet: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. A Apache Commons Lang (2024) szerint a DurationFormatUtils könyvtár további formázási lehetőségeket biztosít.
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")
}
}
Az első hiba — a Duration és Period összekeverése dátumokkal való munka során. A Duration másodperceket mér, így a Duration.ofDays(1) mindig 24 óra (86400 másodperc), függetlenül a nyári időszámításra váltástól. Ha naptári napra van szüksége, használja a Period.ofDays(1)-et.
A második hiba — nanoszekundumok elvesztése konverzió során. A Duration tárolhat nanoszekundumokat, de a toMillis() és toSeconds() eldobják azokat. Pontos számításokhoz használja a toNanos()-t vagy dolgozzon közvetlenül a Duration-ral, primitív típusokra konvertálás nélkül.
A harmadik hiba — a negatív Duration figyelmen kívül hagyása. A Duration.between(start, end) start - end értéket ad vissza. Ha start end után van, a Duration negatív lesz. Az abs() metódus segít az abszolút érték előállításában, az isNegative() pedig az argumentumok sorrendjének ellenőrzésében.
A negyedik hiba — a Duration helytelen formázása a UI számára. A Duration.toString() ISO-8601-et ad vissza, ami olvashatatlan. Mindig kézzel formázza a Duration-t a felhasználó számára, a toHours(), toMinutes() és toSeconds() használatával a megfelelő osztási maradékkal.
Gyakran Ismételt Kérdések
Igen, a Duration lehet negatív. A Duration.between(start, end) start - end értéket ad vissza. Ha start end után van, a Duration negatív lesz. Használja az abs()-t az abszolút érték előállításához vagy az isNegative()-t az ellenőrzéshez.
Használja a plus(Duration) metódust vagy a + operátort Kotlinban: duration1 + duration2. Az eredmény — új Duration. A minus(Duration) metódus kivon egy időtartamot a másikból. Minden művelet megváltoztathatatlan és új objektumot ad vissza.
A Duration.ofDays(1) mindig 24 óra (86400 másodperc). A Period.ofDays(1) 1 naptári nap, amely DST esetén 23 vagy 25 óra lehet. Pontos időszámításokhoz használja a Duration-t, naptárihoz — a Period-ot.
Használja a toMillis() metódust. Egy long értéket ad vissza — a Duration-ban lévő ezredmásodpercek számát. Nanoszekundumokhoz használja a toNanos()-t. Figyelem: a toNanos() túlcsordíthatja a long-ot 292 évnél nagyobb értékeknél. Nagy Duration-okhoz használja a toSeconds()-t vagy a toMinutes()-t.
Használja a Duration.between(startTime, endTime)-t. Ha az endTime kisebb, mint a startTime (éjszakai műszak), a Duration negatív lesz. Adjon hozzá 24 órát: duration.plusHours(24), ha feltételezi, hogy az endTime a következő nap.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is