Duration — co to je, výpočet doby trvání v Androidu

Autor: IT Sectr Publikováno: 2026-07-13 Doba čtení: 9 min

Duration — neměnná třída z balíčku java.time, představující dobu trvání mezi dvěma okamžiky v sekundách a nanosekundách. Duration měří časově založené množství času — hodiny, minuty, sekundy, milisekundy a nanosekundy. Podle specifikace Oracle Java 17 (2024), na rozdíl od Period (který měří roky-měsíce-dny), Duration pracuje s přesnými časovými jednotkami a nezávisí na kalendáři.

Hlavní body

  • Duration — neměnná třída pro měření doby trvání v sekundách a nanosekundách.
  • Na rozdíl od Period, Duration pracuje s časově založenými jednotkami (hodiny, minuty, sekundy), nikoli s datově založenými (dny, měsíce, roky).
  • Vytváří se pomocí Duration.between(start, end), Duration.ofMinutes(), Duration.ofHours() a dalších statických továren.
  • Podporuje aritmetické operace: plus(), minus(), multipliedBy(), dividedBy(), negated().
  • Pro vývoj Android je Duration užitečný pro výpočet časových limitů, synchronizačních intervalů a doby trvání operací.

Co je Duration?

Duration — je třída, která modeluje množství času v sekundách a nanosekundách. Představuje časově založenou dobu trvání, tedy fyzický počet sekund, který není vázán na kalendář. Duration lze reprezentovat jako „125 minut” nebo „2 hodiny 5 minut” — na rozdíl od Period, který řekne „2 měsíce”.

Vnitřní reprezentace Duration se skládá ze dvou polí: long seconds (sekundy) a int nanos (nanosekundy, od 0 do 999999999). Hodnota může být záporná — to znamená dobu trvání „zpět” v čase. Maximální hodnota je ±31557014167219200 sekund.

Podle Baeldung (2024), Duration je klíčovou třídou pro výpočet doby trvání operací, nastavení časových limitů a měření výkonu. Duration je neměnná a thread-safe, což umožňuje její použití ve vícevláknovém prostředí bez synchronizace.

Třída implementuje rozhraní Comparable, TemporalAmount a TemporalUnit. TemporalAmount umožňuje použití Duration v metodách plus/minus tříd LocalTime, LocalDateTime, Instant a ZonedDateTime.

Duration vs Period: jaký je rozdíl?

Hlavní rozdíl — Duration měří přesný počet sekund (time-based), zatímco Period měří kalendářní jednotky (date-based): roky, měsíce, dny. Duration říká: „uběhlo 86400 sekund”. Period říká: „uběhl 1 den”. Rozdíl se projevuje při přechodu na letní čas — 1 den v Period je vždy roven 1 dni v kalendáři, zatímco 86400 sekund v Duration může odpovídat 23 nebo 25 hodinám při DST.

Duration se používá pro měření fyzického času: časové limity připojení, doba provedení požadavku, interval mezi dvěma Instant. Period se používá pro kalendářní výpočty: věk osoby (Period.between(datumNarození, dnes)), doba platnosti smlouvy.

Duration pracuje se sekundami a nanosekundami, proto jej lze dělit na části (hodiny, minuty). Period pracuje s roky, měsíci a dny — nedělitelnými kalendářními jednotkami. Podle Oracle Java Tutorial (2024), výběr mezi Duration a Period závisí na typu úkolu: přesný čas vs kalendářní data.

Vytvoření Duration

Nejběžnější způsob — Duration.between(Temporal start, Temporal end). Temporal může být Instant, LocalTime, LocalDateTime, ZonedDateTime — jakýkoli typ implementující Temporal. Metoda vrátí Duration představující rozdíl start - end (může být záporná).

Statické tovární metody: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Existuje také of(long amount, TemporalUnit unit) pro libovolné jednotky — ChronoUnit.HOURS, ChronoUnit.MINUTES a další.

Metoda parse(CharSequence) přijímá řetězec ve formátu ISO-8601: „PT1H30M” (1 hodina 30 minut), „PT45S” (45 sekund), „P2DT3H” (2 dny 3 hodiny). Řetězec vždy začíná „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")

Aritmetika s Duration

Duration podporuje kompletní sadu aritmetických operací. Metody plus(Duration) a minus(Duration) přidávají nebo odebírají jinou dobu trvání. Metody plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() — pro přesné přidávání jednotek.

Pro násobení a dělení se používají multipliedBy(long) a dividedBy(long). Duration.multipliedBy(2) zdvojnásobí dobu trvání. Duration.dividedBy(3) rozdělí na tři části se zaokrouhlením dolů. Metoda negated() obrátí znaménko — kladná se stane zápornou a naopak.

Metoda abs() vrátí Duration s absolutní (kladnou) hodnotou. isNegative() a isZero() — kontroly. toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() — převod do odpovídajících jednotek.

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

Porovnávání Duration

Duration implementuje rozhraní Comparable, což umožňuje přirozené porovnávání dob trvání. Metoda compareTo() vrátí záporné číslo, nulu nebo kladné číslo. Metody isNegative() a isZero() — rychlé kontroly. Pro explicitní porovnání použijte equals() — dvě Duration jsou stejná, pokud mají stejné sekundy a nanosekundy.

Protože Duration může být záporné, porovnání „větší” nebo „menší” funguje s ohledem na znaménko. -5 minut je menší než 2 minuty. Metoda abs() je užitečná, pokud potřebujete porovnávat „absolutní” délky bez ohledu na směr.

V Kotlinu Duration podporuje operátory porovnání pomocí přetěžování operátorů: a < b, a > b, a <= b. Také plus a minus jsou k dispozici jako operátory: a + b, a - b.

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

if (short < long) {
    Log.d("Duration", "5 min je méně než 10")
}

val negative = Duration.ofMinutes(-3)
Log.d("Duration", "Záporný: ${negative.isNegative()}")

Duration v reálnúch úkolech Android

První příklad — nastavení periodické synchronizace se serverem. Duration se používá pro výpočet intervalu mezi synchronizacemi a kontrolu, zda nebyl překročen časový limit bez aktualizace.

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

Druhý příklad — měření doby provedení operace pro protokolování výkonu.

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

Třetí příklad — výpočet zbývajícího času časovače (například pro odpočet do konce akce).

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
}

Převod Duration na řetězec

Metoda toString() vrátí Duration ve formátu ISO-8601: „PT1H30M” (1 hodina 30 minut), „PT45.5S” (45.5 sekund). Tento formát je vhodný pro strojovou výměnu, ale ne pro zobrazení uživateli.

Pro formát čitelný pro člověka použijte toDays(), toHours(), toMinutes(), toSeconds() s ručním sestavením řetězce. Například: „${days} d ${hours} h ${minutes} min”. Všimněte si, že toHours() vrátí celkový počet hodin, nikoli hodiny v rámci dne.

Pro rozdělení Duration na součásti se používá vzorec: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. Podle Apache Commons Lang (2024), knihovna DurationFormatUtils poskytuje další možnosti formátování.

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

Typické chyby

První chyba — záměna Duration a Period při práci s daty. Duration měří sekundy, proto Duration.ofDays(1) je vždy 24 hodin (86400 sekund), bez ohledu na přechod na letní čas. Pokud potřebujete kalendářní den, použijte Period.ofDays(1).

Druhá chyba — ztráta nanosekund při převodu. Duration může ukládat nanosekundy, ale toMillis() a toSeconds() je zahazují. Pro přesné výpočty použijte toNanos() nebo pracujte přímo s Duration, bez převodu na primitivní typy.

Třetí chyba — ignorování záporných Duration. Duration.between(start, end) vrátí start - end. Pokud je start po end, Duration bude záporné. Metoda abs() pomáhá získat absolutní hodnotu a isNegative() — zkontrolovat pořadí argumentů.

Čtvrtá chyba — nesprávné formátování Duration pro UI. Duration.toString() vrátí ISO-8601, který je nečitelný. Vždy formátujte Duration ručně pro zobrazení uživateli, pomocí toHours(), toMinutes() a toSeconds() se správným zbytkem po dělení.

Často kladené otázky

Může být Duration záporné?

Ano, Duration může být záporné. Duration.between(start, end) vrátí start - end. Pokud je start po end, Duration bude záporné. Použijte abs() pro získání absolutní hodnoty nebo isNegative() pro kontrolu.

Jak sečíst dvě Duration?

Použijte metodu plus(Duration) nebo operátor + v Kotlinu: duration1 + duration2. Výsledek — nové Duration. Metoda minus(Duration) odečítá jednu dobu trvání od druhé. Všechny operace jsou neměnné a vracejí nový objekt.

Čím se liší Duration.ofDays(1) od Period.ofDays(1)?

Duration.ofDays(1) je vždy 24 hodin (86400 sekund). Period.ofDays(1) je 1 kalendářní den, který při DST může být 23 nebo 25 hodin. Pro výpočty s přesným časem použijte Duration, pro kalendářní — Period.

Jak převést Duration na milisekundy?

Použijte metodu toMillis(). Vrátí long — počet milisekund v Duration. Pro nanosekundy použijte toNanos(). Pozor: toNanos() může přetéct long při hodnotách > 292 let. Pro velké Duration použijte toSeconds() nebo toMinutes().

Jak vypočítat Duration mezi dvěma LocalTime?

Použijte Duration.between(startTime, endTime). Pokud je endTime menší než startTime (noční směna), Duration bude záporné. Přidejte 24 hodin: duration.plusHours(24), pokud předpokládáte, že endTime je následující den.

Shrnutí

  • Duration — neměnná třída pro časově založenou dobu trvání s přesností na nanosekundy, ideální pro měření intervalů.
  • Hlavní rozdíl od Period — Duration měří sekundy (fyzický čas), Period — kalendářní jednotky.
  • Vytváří se pomocí Duration.between() pro rozdíl mezi okamžiky nebo pomocí statických továren ofMinutes, ofHours, ofDays.
  • Podporuje aritmetiku: plus, minus, multipliedBy, dividedBy, stejně jako porovnání pomocí Comparable a abs.
  • V Androidu se Duration používá pro výpočet časových limitů, synchronizačních intervalů, časovačů a měření výkonu.
  • Při zobrazení uživateli formátujte Duration ručně — toString() vrátí ISO-8601, nečitelný pro člověka.
  • Mějte na paměti, že Duration může být záporné — kontrolujte isNegative() a použijte abs() pro správné výpočty.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také