ThreeTenABP — pustaka adaptor untuk Android, menyediakan API java.time (paket org.threeten.bp) pada perangkat dengan Android di bawah 8 (API < 26). Menurut spesifikasi Jake Wharton (GitHub, 2023), pustaka ini merupakan pembungkus di atas proyek ThreeTen-Backport, diadaptasi untuk Android dengan mempertimbangkan optimasi sumber daya dan dukungan tzdata melalui AssetManager.
Poin Utama
ThreeTenABP (ThreeTen Android Backport) — pustaka yang dibuat oleh Jake Wharton untuk menggunakan API tanggal/waktu Java 8 pada versi Android lama. Pustaka ini merupakan adaptor untuk proyek ThreeTen-Backport, yang memporting java.time (JSR-310) ke Java 7 dan Android API < 26.
Masalah utama yang dipecahkan oleh pustaka ini: Android hingga versi 8 (API 26) tidak menyertakan java.time dalam bawaan standar. Pengembang terpaksa menggunakan java.util.Date/Calendar atau menambahkan Joda-Time. ThreeTenABP menyediakan API modern yang sama dengan java.time bawaan, tetapi melalui paket org.threeten.bp.
Menurut repositori GitHub (2023), pustaka ini dioptimalkan untuk Android: data tzdata (IANA Time Zone Database) disimpan di assets dan dimuat melalui AssetManager, bukan melalui classpath seperti di desktop. Ini mengurangi ukuran APK dan mempercepat pemuatan.
Versi stabil terakhir — 1.4.0 (Agustus 2021). Pustaka ini dalam mode dukungan, karena dengan meluasnya desugaring kebutuhan akan pustaka ini menurun, tetapi tetap relevan untuk proyek dengan API minimal < 26.
Sebelum munculnya java.time di Java 8 (2014), pengembang menggunakan java.util.Date dan java.util.Calendar. Kelas-kelas ini memiliki kekurangan serius: Date bersifat mutable, Calendar menggunakan konstanta yang tidak intuitif (Calendar.JANUARY = 0), kedua kelas tidak thread-safe dan rentan terhadap kesalahan saat bekerja dengan zona waktu.
Joda-Time adalah standar de facto sebelum Java 8, tetapi pembuatnya Stephen Colebourne merancang java.time sebagai pengganti resmi, berdasarkan pengalaman Joda-Time dan mempertimbangkan kekurangannya. Paket java.time menjadi bagian dari JDK 8, tetapi Android tidak mendapatkannya hingga API 26.
ThreeTen-Backport — port java.time ke Java 7, dibuat oleh penulis yang sama (Stephen Colebourne). Ini mencakup semua kelas utama: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP mengadaptasi port ini untuk Android, menambahkan inisialisasi melalui AssetsManager dan optimasi untuk perangkat seluler.
Dengan demikian, ThreeTenABP memungkinkan penggunaan API tanggal/waktu modern pada perangkat dengan Android 4.0+ (API 14+) tanpa perlu menunggu pembaruan OS.
Penghubungan dilakukan dalam dua langkah: menambahkan dependensi di build.gradle (app-level) dan inisialisasi di kelas Application. Penting: ThreeTenABP memerlukan compileSdk tidak kurang dari 21 dan Gradle versi tidak kurang dari 4.0.
Dependensi ditambahkan di bagian dependencies: implementation “com.jakewharton.threetenabp:threetenabp:1.4.0”. Sejak rilis 1.4.0, pustaka ini tidak diperbarui karena stabil dan mencakup semua kasus yang diperlukan.
Menurut dokumentasi resmi, pustaka ini menyertakan tzdata di assets. Jika aplikasi sudah memiliki folder assets dengan file lain, ThreeTenABP dapat hidup berdampingan dengan benar. Ukuran tzdata sekitar 200 KB dalam bentuk terkompresi.
// build.gradle (tingkat aplikasi)
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation "com.jakewharton.threetenabp:threetenabp:1.4.0"
}
Sebelum menggunakan kelas apa pun dari org.threeten.bp, pustaka harus diinisialisasi. Inisialisasi dilakukan sekali di Application.onCreate() melalui panggilan AndroidThreeTen.init(this).
Inisialisasi memuat data tzdata dari assets dan mengonfigurasi jam sistem. Tanpa panggilan init(), metode now() akan melempar pengecualian IllegalStateException dengan pesan bahwa pustaka belum diinisialisasi.
Untuk pengujian, dapat digunakan AndroidThreeTen.init(applicationContext, zoneId) — kelebihan beban dengan penentuan zona waktu secara eksplisit. Ini berguna untuk perilaku pengujian yang dapat diprediksi. Jika hanya diperlukan inisialisasi dasar tanpa tzdata — gunakan AndroidThreeTen.initWithoutFiles(context).
class App : Application() {
override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this)
}
}
// Penggunaan setelah inisialisasi
val today = LocalDate.now()
val now = LocalDateTime.now()
ThreeTenABP menyediakan semua kelas utama java.time, tetapi dalam paket org.threeten.bp. API-nya hampir identik dengan java.time asli, yang menyederhanakan migrasi saat beralih ke API 26+.
Kelas utama:
Kelas pembantu juga didukung: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Zona waktu disertakan dengan pustaka (IANA tzdata). Versi tzdata di ThreeTenABP 1.4.0 sesuai dengan 2021a.
Mulai dari Android Gradle Plugin 4.0 (2020) dan desugar_jdk_libs, pengembang mendapatkan kemampuan untuk menggunakan java.time di semua versi Android melalui coreLibraryDesugaring. Desugaring mentransformasi bytecode sehingga panggilan java.time berfungsi pada API lama tanpa pustaka tambahan.
Kelebihan desugaring: menggunakan paket java.time asli (bukan org.threeten.bp), tidak memerlukan inisialisasi, integrasi penuh dengan Android Studio. Kekurangan: memerlukan AGP 4.0+, menambah waktu build, ukuran APK dapat bertambah 2-3 MB.
ThreeTenABP tetap menjadi pilihan terbaik untuk proyek legacy yang tidak dapat memperbarui AGP ke 4.0+, atau di mana ukuran APK menjadi kritis. ThreeTenABP juga lebih sederhana dalam pengaturan — satu dependensi dan satu baris inisialisasi sudah cukup. Menurut Stack Overflow (2024), sekitar 30% proyek dengan minSdk < 26 masih menggunakan ThreeTenABP daripada desugaring.
Contoh pertama — bekerja dengan tanggal melalui ThreeTenABP. API-nya identik dengan java.time, tetapi impor berasal dari org.threeten.bp. Ini memungkinkan penulisan kode yang setelah migrasi hanya memerlukan penggantian impor.
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalTime
import org.threeten.bp.Duration
fun isWeekend(date: LocalDate): Boolean {
val dayOfWeek = date.getDayOfWeek()
return dayOfWeek == DayOfWeek.SATURDAY ||
dayOfWeek == DayOfWeek.SUNDAY
}
fun timeBetween(
start: LocalTime, end: LocalTime
): Duration {
return Duration.between(start, end)
}
Contoh kedua — pemformatan tanggal. DateTimeFormatter dari org.threeten.bp bekerja sama seperti di java.time.
import org.threeten.bp.LocalDateTime
import org.threeten.bp.format.DateTimeFormatter
fun formatTimestamp(dateTime: LocalDateTime): String {
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
return dateTime.format(formatter)
}
Contoh ketiga — bekerja dengan ZonedDateTime dan konversi antar zona waktu di ThreeTenABP.
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.ZoneId
fun convertTimeZone(
time: ZonedDateTime,
targetZone: ZoneId
): ZonedDateTime {
return time.withZoneSameInstant(targetZone)
}
Saat menaikkan minSdk ke 26, Anda dapat meninggalkan ThreeTenABP dan beralih ke java.time bawaan. Proses migrasi mencakup beberapa langkah dan memerlukan pengujian yang cermat.
Langkah pertama — mengganti impor. Impor org.threeten.bp diubah menjadi java.time. Dalam sebagian besar kasus, nama kelas sesuai: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. Pengecualian adalah DateTimeFormatter — di ThreeTenABP berada di org.threeten.bp.format, di java.time — di java.time.format.
Langkah kedua — menghapus inisialisasi. Baris AndroidThreeTen.init(this) tidak lagi diperlukan, karena java.time sudah ada di Android SDK. Hapus panggilan dari Application.onCreate() dan dependensi dari build.gradle.
Langkah ketiga — mengganti dependensi dengan desugaring, jika minSdk tetap di bawah 26. Tambahkan isCoreLibraryDesugaringEnabled = true di compileOptions dan dependensi desugar_jdk_libs. Ini akan memastikan java.time berfungsi pada API lama tanpa ThreeTenABP. Menurut Google I/O (2023), desugaring adalah metode yang lebih disukai untuk proyek baru.
// build.gradle — ganti ThreeTenABP dengan desugaring
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
// Hapus: implementation “com.jakewharton.threetenabp:threetenabp:1.4.0”
// Tambahkan:
"coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}
// Hapus AndroidThreeTen.init(this) dari Application
Pertanyaan yang Sering Diajukan
Secara teknis — ya, tetapi tidak masuk akal. Jika desugaring digunakan, java.time bawaan sudah tersedia. Penggunaan kedua pustaka akan menyebabkan duplikasi kode dan peningkatan ukuran APK. Pilih satu pendekatan untuk proyek.
Inisialisasi memuat data IANA Time Zone Database dari assets ke memori. Di JDK standar, tzdata tersedia melalui classpath, tetapi Android menggunakan AssetManager. Metode init() menyalin data ke direktori sistem, membuatnya tersedia untuk ZoneId.
ThreeTenABP mendukung API 14+ (Android 4.0 Ice Cream Sandwich dan lebih tinggi). Untuk penggunaan, diperlukan Java 8 compatibility (sourceCompatibility dan targetCompatibility di compileOptions). Pada API 26+, pustaka tidak diperlukan — gunakan java.time bawaan.
Zona waktu disertakan dengan pustaka. Versi 1.4.0 menyertakan tzdata 2021a. Untuk memperbarui, perlu memperbarui versi ThreeTenABP atau mengganti tzdata secara manual di assets. Versi terbaru tzdata dapat diperoleh dari repositori IANA atau melalui ThreeTen-Backport.
Untuk pengujian unit, gunakan AndroidThreeTen.init(context, zoneId) dengan penentuan zona secara eksplisit. Untuk pengujian Robolectric — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). Untuk pengujian JVM murni tanpa Android — gunakan langsung ThreeTen-Backport tanpa ThreeTenABP.
Kesimpulan
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