Duration — kelas immutable dari paket java.time yang merepresentasikan durasi antara dua momen waktu dalam detik dan nanodetik. Duration mengukur jumlah waktu berbasis waktu — jam, menit, detik, milidetik, dan nanodetik. Menurut spesifikasi Oracle Java 17 (2024), tidak seperti Period (yang mengukur tahun-bulan-hari), Duration bekerja dengan satuan waktu yang tepat dan tidak bergantung pada kalender.
Poin utama
Duration — adalah kelas yang memodelkan jumlah waktu dalam detik dan nanodetik. Ini merepresentasikan durasi berbasis waktu, yaitu jumlah detik fisik, tidak terikat pada kalender. Duration dapat direpresentasikan sebagai “125 menit” atau “2 jam 5 menit” — tidak seperti Period, yang akan mengatakan “2 bulan”.
Representasi internal Duration terdiri dari dua bidang: long seconds (detik) dan int nanos (nanodetik, dari 0 hingga 999999999). Nilai bisa negatif — ini berarti durasi “mundur” dalam waktu. Nilai maksimum adalah ±31557014167219200 detik.
Menurut Baeldung (2024), Duration adalah kelas kunci untuk menghitung durasi operasi, mengatur timeout, dan mengukur kinerja. Duration bersifat immutable dan thread-safe, yang memungkinkan penggunaannya di lingkungan multi-thread tanpa sinkronisasi.
Kelas ini mengimplementasikan antarmuka Comparable, TemporalAmount, dan TemporalUnit. TemporalAmount memungkinkan penggunaan Duration dalam metode plus/minus dari kelas LocalTime, LocalDateTime, Instant, dan ZonedDateTime.
Perbedaan utama — Duration mengukur jumlah detik yang tepat (time-based), sedangkan Period mengukur satuan kalender (date-based): tahun, bulan, hari. Duration mengatakan: “telah berlalu 86400 detik”. Period mengatakan: “telah berlalu 1 hari”. Perbedaannya terlihat saat peralihan ke waktu musim panas — 1 hari di Period selalu sama dengan 1 hari di kalender, sementara 86400 detik di Duration dapat sesuai dengan 23 atau 25 jam saat DST.
Duration digunakan untuk mengukur waktu fisik: timeout koneksi, waktu eksekusi permintaan, interval antara dua Instant. Period digunakan untuk perhitungan kalender: usia seseorang (Period.between(tanggalLahir, hariIni)), masa berlaku kontrak.
Duration bekerja dengan detik dan nanodetik, sehingga dapat dibagi menjadi bagian-bagian (jam, menit). Period bekerja dengan tahun, bulan, dan hari — satuan kalender yang tidak dapat dibagi. Menurut Oracle Java Tutorial (2024), pilihan antara Duration dan Period tergantung pada jenis tugas: waktu yang tepat vs tanggal kalender.
Cara paling umum — Duration.between(Temporal start, Temporal end). Temporal bisa Instant, LocalTime, LocalDateTime, ZonedDateTime — tipe apa pun yang mengimplementasikan Temporal. Metode mengembalikan Duration yang merepresentasikan selisih start - end (bisa negatif).
Metode factory statis: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Ada juga of(long amount, TemporalUnit unit) untuk satuan arbitrer — ChronoUnit.HOURS, ChronoUnit.MINUTES, dan lainnya.
Metode parse(CharSequence) menerima string dalam format ISO-8601: “PT1H30M” (1 jam 30 menit), “PT45S” (45 detik), “P2DT3H” (2 hari 3 jam). String selalu dimulai dengan “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 mendukung rangkaian lengkap operasi aritmatika. Metode plus(Duration) dan minus(Duration) menambah atau mengurangi durasi lain. Metode plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() — untuk penambahan satuan secara tepat.
Untuk perkalian dan pembagian digunakan multipliedBy(long) dan dividedBy(long). Duration.multipliedBy(2) menggandakan durasi. Duration.dividedBy(3) membagi menjadi tiga bagian dengan pembulatan ke bawah. Metode negated() membalikkan tanda — positif menjadi negatif dan sebaliknya.
Metode abs() mengembalikan Duration dengan nilai absolut (positif). isNegative() dan isZero() — pemeriksaan. toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() — konversi ke satuan yang sesuai.
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 mengimplementasikan antarmuka Comparable, yang memungkinkan perbandingan durasi secara alami. Metode compareTo() mengembalikan angka negatif, nol, atau positif. Metode isNegative() dan isZero() — pemeriksaan cepat. Untuk perbandingan eksplisit gunakan equals() — dua Duration sama jika memiliki detik dan nanodetik yang sama.
Karena Duration bisa negatif, perbandingan “lebih besar” atau “lebih kecil” berfungsi dengan mempertimbangkan tanda. -5 menit lebih kecil dari 2 menit. Metode abs() berguna jika Anda perlu membandingkan panjang “ absolut” terlepas dari arah.
Di Kotlin, Duration mendukung operator perbandingan melalui operator overloading: a < b, a > b, a <= b. Juga plus dan minus tersedia sebagai operator: a + b, a - b.
val short = Duration.ofMinutes(5)
val long = Duration.ofMinutes(10)
if (short < long) {
Log.d("Duration", "5 menit kurang dari 10")
}
val negative = Duration.ofMinutes(-3)
Log.d("Duration", "Negatif: ${negative.isNegative()}")
Contoh pertama — mengatur sinkronisasi periodik dengan server. Duration digunakan untuk menghitung interval antar sinkronisasi dan memeriksa apakah batas waktu tanpa pembaruan telah terlampaui.
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)
}
Contoh kedua — mengukur waktu eksekusi operasi untuk logging kinerja.
fun measureExecution(
tag: String,
block: () -> Unit
) {
val start = Instant.now()
block()
val duration = Duration.between(start, Instant.now())
Log.d(tag, "Dieksekusi dalam ${duration.toMillis()} ms")
}
Contoh ketiga — menghitung sisa waktu timer (misalnya, untuk hitung mundur hingga akhir promosi).
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
}
Metode toString() mengembalikan Duration dalam format ISO-8601: “PT1H30M” (1 jam 30 menit), “PT45.5S” (45.5 detik). Format ini nyaman untuk pertukaran mesin, tetapi tidak untuk ditampilkan kepada pengguna.
Untuk format yang dapat dibaca manusia, gunakan toDays(), toHours(), toMinutes(), toSeconds() dengan perakitan string secara manual. Contoh: “${days} h ${hours} j ${minutes} mnt”. Perhatikan bahwa toHours() mengembalikan jumlah total jam, bukan jam dalam sehari.
Untuk memecah Duration menjadi komponen, gunakan rumus: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. Menurut Apache Commons Lang (2024), pustaka DurationFormatUtils menyediakan kemampuan pemformatan tambahan.
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")
}
}
Kesalahan pertama — kebingungan antara Duration dan Period saat bekerja dengan tanggal. Duration mengukur detik, jadi Duration.ofDays(1) selalu 24 jam (86400 detik), terlepas dari peralihan waktu musim panas. Jika Anda membutuhkan hari kalender, gunakan Period.ofDays(1).
Kesalahan kedua — hilangnya nanodetik saat konversi. Duration dapat menyimpan nanodetik, tetapi toMillis() dan toSeconds() membuangnya. Untuk perhitungan yang akurat, gunakan toNanos() atau bekerja langsung dengan Duration, tanpa konversi ke tipe primitif.
Kesalahan ketiga — mengabaikan Duration negatif. Duration.between(start, end) mengembalikan start - end. Jika start setelah end, Duration akan negatif. Metode abs() membantu mendapatkan nilai absolut, dan isNegative() untuk memeriksa urutan argumen.
Kesalahan keempat — pemformatan Duration yang salah untuk UI. Duration.toString() mengembalikan ISO-8601 yang tidak dapat dibaca. Selalu format Duration secara manual untuk ditampilkan kepada pengguna, menggunakan toHours(), toMinutes(), dan toSeconds() dengan sisa pembagian yang benar.
Pertanyaan Umum
Ya, Duration bisa negatif. Duration.between(start, end) mengembalikan start - end. Jika start setelah end, Duration akan negatif. Gunakan abs() untuk mendapatkan nilai absolut atau isNegative() untuk memeriksa.
Gunakan metode plus(Duration) atau operator + di Kotlin: duration1 + duration2. Hasilnya — Duration baru. Metode minus(Duration) mengurangi satu durasi dari yang lain. Semua operasi bersifat immutable dan mengembalikan objek baru.
Duration.ofDays(1) selalu 24 jam (86400 detik). Period.ofDays(1) adalah 1 hari kalender yang saat DST bisa 23 atau 25 jam. Untuk perhitungan dengan waktu yang tepat gunakan Duration, untuk kalender — Period.
Gunakan metode toMillis(). Mengembalikan long — jumlah milidetik dalam Duration. Untuk nanodetik gunakan toNanos(). Perhatian: toNanos() dapat meluapkan long pada nilai > 292 tahun. Untuk Duration besar gunakan toSeconds() atau toMinutes().
Gunakan Duration.between(startTime, endTime). Jika endTime lebih kecil dari startTime (shift malam), Duration akan negatif. Tambahkan 24 jam: duration.plusHours(24), jika Anda berasumsi endTime adalah hari berikutnya.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga