ThreeTenABP: wat is het, java.time-bibliotheek voor Android

Auteur: IT Sectr Gepubliceerd: 2026-07-14 Leestijd: 11 min

ThreeTenABP — adapterbibliotheek voor Android die de java.time API (pakket org.threeten.bp) biedt op apparaten met Android onder 8 (API < 26). Volgens de specificatie Jake Wharton (GitHub, 2023) is de bibliotheek een wrapper rond het ThreeTen-Backport-project, aangepast voor Android met optimalisatie van bronnen en ondersteuning van tzdata via AssetManager.

Belangrijkste punten

  • ThreeTenABP — Android-adapter voor ThreeTen-Backport, die java.time biedt op API < 26.
  • Wordt aangesloten via Gradle: implementation „com.jakewharton.threetenabp:threetenabp:1.4.x”.
  • Vereist initialisatie in Application.onCreate() via AndroidThreeTen.init(this).
  • Gebruikt het pakket org.threeten.bp in plaats van java.time — de API is vrijwel identiek.
  • Met de komst van desugaring (AGP 4.0+) is ThreeTenABP optioneel geworden en wordt het gebruikt voor legacy-projecten.

Wat is ThreeTenABP?

ThreeTenABP (ThreeTen Android Backport) — een bibliotheek gemaakt door Jake Wharton voor het gebruik van de Java 8 datum/tijd API op oudere Android-versies. Het is een adapter voor het ThreeTen-Backport-project, dat java.time (JSR-310) port naar Java 7 en Android API < 26.

Het belangrijkste probleem dat de bibliotheek oplost: Android tot versie 8 (API 26) bevatte java.time niet in de standaardlevering. Ontwikkelaars waren gedwongen java.util.Date/Calendar te gebruiken of Joda-Time toe te voegen. ThreeTenABP biedt dezelfde moderne API als ingebouwde java.time, maar via het pakket org.threeten.bp.

Volgens GitHub-repository (2023) is de bibliotheek geoptimaliseerd voor Android: tzdata-gegevens (IANA Time Zone Database) worden opgeslagen in assets en geladen via AssetManager, niet via classpath zoals op desktop. Dit verkleint de APK-grootte en versnelt het laden.

Laatste stabiele versie — 1.4.0 (augustus 2021). De bibliotheek is in onderhoudsmodus, omdat met de brede verspreiding van desugaring de behoefte eraan afneemt, maar het blijft relevant voor projecten met minimaal API < 26.

Waarom is een backport van java.time nodig?

Vóór de komst van java.time in Java 8 (2014) gebruikten ontwikkelaars java.util.Date en java.util.Calendar. Deze klassen hebben ernstige tekortkomingen: Date is mutabel, Calendar gebruikt niet-intuïtieve constanten (Calendar.JANUARY = 0), beide klassen zijn niet thread-safe en vatbaar voor fouten bij het werken met tijdzones.

Joda-Time was de de facto standaard vóór Java 8, maar de maker Stephen Colebourne ontwierp java.time als officiële vervanging, gebaseerd op de ervaring van Joda-Time en rekening houdend met de tekortkomingen ervan. Het pakket java.time werd onderdeel van JDK 8, maar Android kreeg het pas met API 26.

ThreeTen-Backport — een port van java.time naar Java 7, gemaakt door dezelfde auteur (Stephen Colebourne). Het bevat alle belangrijke klassen: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP past deze port aan voor Android, met initialisatie via AssetsManager en optimalisatie voor mobiele apparaten.

ThreeTenABP maakt het dus mogelijk moderne datum/tijd API te gebruiken op apparaten met Android 4.0+ (API 14+) zonder te wachten op een OS-update.

ThreeTenABP aansluiten in een Android-project

Aansluiten gebeurt in twee stappen: toevoegen van de afhankelijkheid in build.gradle (app-level) en initialisatie in de Application-klasse. Belangrijk: ThreeTenABP vereist compileSdk niet lager dan 21 en Gradle-versie niet lager dan 4.0.

De afhankelijkheid wordt toegevoegd in de sectie dependencies: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”. Sinds de release 1.4.0 is de bibliotheek niet bijgewerkt, omdat deze stabiel is en alle benodigde gevallen dekt.

Volgens officiële documentatie bevat de bibliotheek tzdata in assets. Als de app al een assets-map met andere bestanden heeft, kan ThreeTenABP er correct mee samenwerken. De grootte van tzdata is ongeveer 200 KB in gecomprimeerde vorm.

groovy
// build.gradle (app-niveau)
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation "com.jakewharton.threetenabp:threetenabp:1.4.0"
}

ThreeTenABP initialiseren

Voordat een klasse uit org.threeten.bp wordt gebruikt, moet de bibliotheek worden geïnitialiseerd. Initialisatie gebeurt eenmalig in Application.onCreate() via de aanroep AndroidThreeTen.init(this).

Initialisatie laadt tzdata-gegevens uit assets en configureert de systeemklok. Zonder aanroep van init() zullen now()-methoden een IllegalStateException geven met de melding dat de bibliotheek niet is geïnitialiseerd.

Voor tests kan AndroidThreeTen.init(applicationContext, zoneId) worden gebruikt — een overload met expliciete opgave van de tijdzone. Dit is handig voor voorspelbaar testgedrag. Als alleen basisinitialisatie zonder tzdata nodig is — gebruik dan AndroidThreeTen.initWithoutFiles(context).

kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}

// Gebruik na initialisatie
val today = LocalDate.now()
val now = LocalDateTime.now()

Welke klassen zijn beschikbaar?

ThreeTenABP biedt alle belangrijke java.time-klassen, maar in het pakket org.threeten.bp. De API is vrijwel identiek aan de originele java.time, wat migratie naar API 26+ vereenvoudigt.

Belangrijkste klassen:

  • LocalDate — datum zonder tijd en tijdzone
  • LocalTime — tijd zonder datum en tijdzone
  • LocalDateTime — datum en tijd zonder tijdzone
  • ZonedDateTime — datum en tijd met tijdzone
  • OffsetDateTime — datum en tijd met vaste offset
  • OffsetTime — tijd met vaste offset
  • Instant — tijdstip in UTC
  • Duration — time-based duur
  • Period — date-based periode
  • DateTimeFormatter — formattering en parsing
  • ZoneId / ZoneOffset — tijdzones

Ondersteunde hulpklassen: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Tijdzones worden meegeleverd met de bibliotheek (IANA tzdata). De tzdata-versie in ThreeTenABP 1.4.0 komt overeen met 2021a.

ThreeTenABP vs desugaring

Sinds Android Gradle Plugin 4.0 (2020) en desugar_jdk_libs hebben ontwikkelaars de mogelijkheid gekregen om java.time op alle Android-versies te gebruiken via coreLibraryDesugaring. Desugaring transformeert bytecode zodat java.time-aanroepen werken op oude API's zonder extra bibliotheken.

Voordelen van desugaring: het originele java.time-pakket wordt gebruikt (niet org.threeten.bp), geen initialisatie vereist, volledige integratie met Android Studio. Nadelen: vereist AGP 4.0+, voegt bouwtijd toe, APK-grootte kan met 2-3 MB toenemen.

ThreeTenABP blijft de beste keuze voor legacy-projecten die AGP niet kunnen updaten naar 4.0+, of waar APK-grootte kritisch is. ThreeTenABP is ook eenvoudiger in te stellen — één afhankelijkheid en één regel initialisatie zijn voldoende. Volgens Stack Overflow (2024) gebruikt ongeveer 30% van de projecten met minSdk < 26 nog ThreeTenABP in plaats van desugaring.

Gebruiksvoorbeelden

Eerste voorbeeld — werken met datums via ThreeTenABP. De API is identiek aan java.time, maar imports komen uit org.threeten.bp. Dit maakt het mogelijk code te schrijven die na migratie alleen importwijzigingen nodig heeft.

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

Tweede voorbeeld — datum formattering. DateTimeFormatter uit org.threeten.bp werkt hetzelfde als in java.time.

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

Derde voorbeeld — werken met ZonedDateTime en conversie tussen tijdzones in ThreeTenABP.

kotlin
import org.threeten.bp.ZonedDateTime
import org.threeten.bp.ZoneId

fun convertTimeZone(
    time: ZonedDateTime,
    targetZone: ZoneId
): ZonedDateTime {
    return time.withZoneSameInstant(targetZone)
}

Migratie van ThreeTenABP naar ingebouwde java.time

Bij verhoging van minSdk naar 26 kan ThreeTenABP worden losgelaten en overgestapt op ingebouwde java.time. Het migratieproces omvat verschillende stappen en vereist grondig testen.

Eerste stap — vervangen van imports. Imports van org.threeten.bp worden gewijzigd naar java.time. In de meeste gevallen komen klassennamen overeen: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. Uitzondering is DateTimeFormatter — in ThreeTenABP in org.threeten.bp.format, in java.time in java.time.format.

Tweede stap — verwijderen van initialisatie. De regel AndroidThreeTen.init(this) is niet meer nodig, omdat java.time is ingebouwd in Android SDK. Verwijder de aanroep uit Application.onCreate() en de afhankelijkheid uit build.gradle.

Derde stap — vervangen van de afhankelijkheid door desugaring, als minSdk onder 26 blijft. Voeg isCoreLibraryDesugaringEnabled = true toe in compileOptions en de afhankelijkheid desugar_jdk_libs. Dit zorgt voor werking van java.time op oude API's zonder ThreeTenABP. Volgens Google I/O (2023) is desugaring de voorkeursmethode voor nieuwe projecten.

groovy
// build.gradle — vervang ThreeTenABP door desugaring
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Verwijder: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”
    // Voeg toe:
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

// Verwijder AndroidThreeTen.init(this) uit Application

Veelgestelde vragen

Kan ThreeTenABP samen met desugaring worden gebruikt?

Technisch — ja, maar het heeft geen zin. Als desugaring wordt gebruikt, is ingebouwde java-time al beschikbaar. Gebruik van beide bibliotheken leidt tot codeduplicatie en toename van de APK-grootte. Kies één aanpak voor het project.

Waarom vereist ThreeTenABP initialisatie in Application?

Initialisatie laadt de IANA Time Zone Database-gegevens uit assets in het geheugen. Op standaard JDK is tzdata beschikbaar via classpath, maar Android gebruikt AssetManager. De methode init() kopieert gegevens naar de systeemmap, waardoor ze beschikbaar worden voor ZoneId.

Welke Android-versies ondersteunt ThreeTenABP?

ThreeTenABP ondersteunt API 14+ (Android 4.0 Ice Cream Sandwich en hoger). Voor gebruik is Java 8 compatibility vereist (sourceCompatibility en targetCompatibility in compileOptions). Op API 26+ is de bibliotheek niet nodig — gebruik ingebouwde java.time.

Hoe tijdzones bijwerken in ThreeTenABP?

Tijdzones worden meegeleverd met de bibliotheek. Versie 1.4.0 bevat tzdata 2021a. Voor bijwerken moet de ThreeTenABP-versie worden bijgewerkt of handmatig tzdata in assets worden vervangen. Nieuwste tzdata-versies zijn verkrijgbaar via de IANA-repository of via ThreeTen-Backport.

Hoe code testen met ThreeTenABP?

Voor unittesten gebruikt u AndroidThreeTen.init(context, zoneId) met expliciete zone-opgave. Voor Robolectric-tests — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). Voor pure JVM-tests zonder Android — gebruik direct ThreeTen-Backport zonder ThreeTenABP.

Samenvatting

  • ThreeTenABP — Android-adapter voor ThreeTen-Backport, die java.time API biedt op apparaten met Android < 8 (API < 26).
  • Wordt aangesloten via Gradle-afhankelijkheid com.jakewharton.threetenabp:threetenabp:1.4.0 en vereist initialisatie AndroidThreeTen.init(this) in Application.onCreate().
  • Gebruikt het pakket org.threeten.bp in plaats van java.time — de API is vrijwel identiek, wat migratie naar API 26+ vereenvoudigt.
  • Belangrijkste klassen: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter — allemaal beschikbaar in ThreeTenABP.
  • Met de komst van desugaring (AGP 4.0+) is ThreeTenABP optioneel geworden, maar blijft relevant voor legacy-projecten of bij APK-groottebeperkingen.
  • Bij migratie naar java.time vervangt u imports org.threeten.bp → java.time, verwijdert u AndroidThreeTen.init() en vervangt u de afhankelijkheid door desugar_jdk_libs.
  • Voor testen gebruikt u AndroidThreeTen.init(context, zoneId) met expliciete zone-opgave voor voorspelbaar gedrag.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook