Duration — en oföränderlig klass från paketet java.time som representerar tidslängden mellan två tidpunkter i sekunder och nanosekunder. Duration mäter tidsbaserad tid — timmar, minuter, sekunder, millisekunder och nanosekunder. Enligt specifikationen från Oracle Java 17 (2024), till skillnad från Period (som mäter år-månader-dagar), arbetar Duration med exakta tidsenheter och är inte beroende av kalendern.
Huvudpunkter
Duration — är en klass som modellerar mängden tid i sekunder och nanosekunder. Den representerar en tidsbaserad varaktighet, det vill säga det fysiska antalet sekunder, inte bundet till någon kalender. Duration kan representeras som “125 minuter” eller “2 timmar 5 minuter” — till skillnad från Period, som skulle säga “2 månader”.
Den interna representationen av Duration består av två fält: long seconds (sekunder) och int nanos (nanosekunder, från 0 till 999999999). Värdet kan vara negativt — detta innebär en varaktighet “bakåt” i tiden. Maxvärdet är ±31557014167219200 sekunder.
Enligt Baeldung (2024), är Duration nyckelklassen för att beräkna operationsvaraktighet, ställa in timeout och mäta prestanda. Duration är oföränderlig och trådsäker, vilket gör den användbar i en flertrådig miljö utan synkronisering.
Klassen implementerar gränssnitten Comparable, TemporalAmount och TemporalUnit. TemporalAmount möjliggör användning av Duration i plus/minus-metoderna för klasserna LocalTime, LocalDateTime, Instant och ZonedDateTime.
Huvudskillnaden — Duration mäter det exakta antalet sekunder (tidsbaserat), medan Period mäter kalenderenheter (datumbaserat): år, månader, dagar. Duration säger: “86400 sekunder har gått”. Period säger: “1 dag har gått”. Skillnaden blir tydlig vid övergång till sommartid — 1 dag i Period är alltid lika med 1 dag i kalendern, medan 86400 sekunder i Duration kan motsvara 23 eller 25 timmar vid DST.
Duration används för att mäta fysisk tid: anslutningstimeout, utförandetid för en begäran, intervall mellan två Instant. Period används för kalenderberäkningar: en persons ålder (Period.between(födelsedatum, idag)), kontrakts giltighetstid.
Duration arbetar med sekunder och nanosekunder, så den kan delas upp i delar (timmar, minuter). Period arbetar med år, månader och dagar — odelbara kalenderenheter. Enligt Oracle Java Tutorial (2024), beror valet mellan Duration och Period på typen av uppgift: exakt tid vs kalenderdatum.
Det vanligaste sättet — Duration.between(Temporal start, Temporal end). Temporal kan vara Instant, LocalTime, LocalDateTime, ZonedDateTime — vilken typ som helst som implementerar Temporal. Metoden returnerar en Duration som representerar skillnaden start - end (kan vara negativ).
Statiska fabriksmetoder: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Det finns också of(long amount, TemporalUnit unit) för godtyckliga enheter — ChronoUnit.HOURS, ChronoUnit.MINUTES och andra.
Metoden parse(CharSequence) accepterar en sträng i ISO-8601-format: “PT1H30M” (1 timme 30 minuter), “PT45S” (45 sekunder), “P2DT3H” (2 dagar 3 timmar). Strängen börjar alltid med “PT” (Period of Time).
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")
Duration stöder en komplett uppsättning aritmetiska operationer. Metoderna plus(Duration) och minus(Duration) lägger till eller subtraherar en annan varaktighet. Metoderna plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() — för exakt tillägg av enheter.
För multiplikation och division används multipliedBy(long) och dividedBy(long). Duration.multipliedBy(2) fördubblar varaktigheten. Duration.dividedBy(3) delar i tre delar med avrundning nedåt. Metoden negated() vänder tecknet — positiv blir negativ och vice versa.
Metoden abs() returnerar en Duration med absolut (positivt) värde. isNegative() och isZero() — kontroller. toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() — konvertering till motsvarande enheter.
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()
Duration implementerar gränssnittet Comparable, vilket möjliggör naturlig jämförelse av varaktigheter. Metoden compareTo() returnerar ett negativt tal, noll eller ett positivt tal. Metoderna isNegative() och isZero() — snabba kontroller. För explicit jämförelse använd equals() — två Duration är lika om de har samma sekunder och nanosekunder.
Eftersom Duration kan vara negativt, fungerar jämförelse ‖större” eller ‖mindre” med hänsyn till tecknet. -5 minuter är mindre än 2 minuter. Metoden abs() är användbar om du behöver jämföra ‖absoluta” längder oavsett riktning.
I Kotlin stöder Duration jämförelseoperatorer genom operatoröverlagring: a < b, a > b, a <= b. Även plus och minus finns som operatorer: a + b, a - b.
val short = Duration.ofMinutes(5)
val long = Duration.ofMinutes(10)
if (short < long) {
Log.d("Duration", "5 min är mindre än 10")
}
val negative = Duration.ofMinutes(-3)
Log.d("Duration", "Negativ: ${negative.isNegative()}")
Första exemplet — konfigurering av periodisk synkronisering med servern. Duration används för att beräkna intervallet mellan synkroniseringar och kontrollera om tidsgränsen utan uppdatering har överskridits.
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)
}
Andra exemplet — mätning av exekveringstiden för en operation för prestandalogging.
fun measureExecution(
tag: String,
block: () -> Unit
) {
val start = Instant.now()
block()
val duration = Duration.between(start, Instant.now())
Log.d(tag, "Utfördes på ${duration.toMillis()} ms")
}
Tredje exemplet — beräkning av återstående tid för en timer (till exempel för nedräkning till slutet av en kampanj).
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
}
Metoden toString() returnerar Duration i ISO-8601-format: “PT1H30M” (1 timme 30 minuter), “PT45.5S” (45.5 sekunder). Detta format är praktiskt för maskinutbyte, men inte för visning för användaren.
För ett mänskligt läsligt format, använd toDays(), toHours(), toMinutes(), toSeconds() med manuell sammansättning av strängen. Till exempel: “${days} d ${hours} h ${minutes} min”. Observera att toHours() returnerar det totala antalet timmar, inte timmarna inom en dag.
För uppdelning av Duration i komponenter används formeln: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. Enligt Apache Commons Lang (2024), tillhandahåller biblioteket DurationFormatUtils ytterligare formateringsmöjligheter.
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")
}
}
Första misstaget — förväxling av Duration och Period vid arbete med datum. Duration mäter sekunder, så Duration.ofDays(1) är alltid 24 timmar (86400 sekunder), oavsett övergång till sommartid. Om du behöver en kalenderdag, använd Period.ofDays(1).
Andra misstaget — förlust av nanosekunder vid konvertering. Duration kan lagra nanosekunder, men toMillis() och toSeconds() kastar bort dem. För exakta beräkningar, använd toNanos() eller arbeta direkt med Duration, utan konvertering till primitiva typer.
Tredje misstaget — ignorering av negativa Duration. Duration.between(start, end) returnerar start - end. Om start är efter end, kommer Duration att vara negativ. Metoden abs() hjälper till att få det absoluta värdet, och isNegative() — att kontrollera argumentordningen.
Fjärde misstaget — felaktig formatering av Duration för UI. Duration.toString() returnerar ISO-8601, som är oläslig. Formatera alltid Duration manuellt för visning för användaren, med toHours(), toMinutes() och toSeconds() med korrekt rest vid division.
Vanliga frågor
Ja, Duration kan vara negativt. Duration.between(start, end) returnerar start - end. Om start är efter end, kommer Duration att vara negativ. Använd abs() för att få det absoluta värdet eller isNegative() för att kontrollera.
Använd metoden plus(Duration) eller operatorn + i Kotlin: duration1 + duration2. Resultatet — en ny Duration. Metoden minus(Duration) subtraherar en varaktighet från en annan. Alla operationer är oföränderliga och returnerar ett nytt objekt.
Duration.ofDays(1) är alltid 24 timmar (86400 sekunder). Period.ofDays(1) är 1 kalenderdag som vid DST kan vara 23 eller 25 timmar. För beräkningar med exakt tid, använd Duration, för kalenderberäkningar — Period.
Använd metoden toMillis(). Den returnerar en long — antalet millisekunder i Duration. För nanosekunder, använd toNanos(). Observera: toNanos() kan överskrida long vid värden > 292 år. För stora Duration, använd toSeconds() eller toMinutes().
Använd Duration.between(startTime, endTime). Om endTime är mindre än startTime (nattpass), kommer Duration att vara negativ. Lägg till 24 timmar: duration.plusHours(24), om du antar att endTime är nästa dag.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också