ThreeTenABP: Was ist das, java.time Bibliothek für Android

Autor: IT Sectr Veröffentlicht: 2026-07-14 Lesezeit: 11 Min.

ThreeTenABP ist eine Adapterbibliothek für Android, die die java.time-API (Paket org.threeten.bp) auf Geräten mit Android unter 8 (API < 26) bereitstellt. Laut der Spezifikation von Jake Wharton (GitHub, 2023) ist die Bibliothek ein Wrapper um das ThreeTen-Backport-Projekt, das für Android mit Ressourcenoptimierung und tzdata-Unterstützung über AssetManager angepasst wurde.

Wichtige Punkte

  • ThreeTenABP ist ein Android-Adapter für ThreeTen-Backport, der java.time auf API < 26 bereitstellt.
  • Wird über Gradle hinzugefügt: implementation "com.jakewharton.threetenabp:threetenabp:1.4.x".
  • Erfordert Initialisierung in Application.onCreate() über AndroidThreeTen.init(this).
  • Verwendet das Paket org.threeten.bp statt java.time — die API ist praktisch identisch.
  • Mit dem Aufkommen von Desugaring (AGP 4.0+) ist ThreeTenABP optional geworden und wird für Legacy-Projekte verwendet.

Was ist ThreeTenABP?

ThreeTenABP (ThreeTen Android Backport) ist eine von Jake Wharton erstellte Bibliothek zur Verwendung der Java 8 Datums-/Zeit-API auf älteren Android-Versionen. Sie ist ein Adapter für das ThreeTen-Backport-Projekt, das java.time (JSR-310) auf Java 7 und Android API < 26 portiert.

Das Hauptproblem, das die Bibliothek löst: Android vor Version 8 (API 26) enthielt java.time nicht in der Standarddistribution. Entwickler waren gezwungen, java.util.Date/Calendar zu verwenden oder Joda-Time hinzuzufügen. ThreeTenABP bietet dieselbe moderne API wie integriertes java.time, aber über das Paket org.threeten.bp.

Laut dem GitHub-Repository (2023) ist die Bibliothek für Android optimiert: tzdata (IANA Time Zone Database) wird in Assets gespeichert und über AssetManager geladen, anstatt über Classpath wie auf dem Desktop. Dies reduziert die APK-Größe und beschleunigt das Laden.

Die neueste stabile Version ist 1.4.0 (August 2021). Die Bibliothek befindet sich im Wartungsmodus, da mit der weit verbreiteten Einführung von Desugaring die Notwendigkeit dafür abnimmt, aber sie bleibt für Projekte mit minimaler API < 26 relevant.

Warum wird ein java.time Backport benötigt?

Bevor java.time in Java 8 (2014) eingeführt wurde, verwendeten Entwickler java.util.Date und java.util.Calendar. Diese Klassen haben schwerwiegende Nachteile: Date ist veränderbar, Calendar verwendet nicht intuitive Konstanten (Calendar.JANUARY = 0), beide Klassen sind nicht threadsicher und neigen zu Fehlern bei der Arbeit mit Zeitzonen.

Joda-Time war vor Java 8 der De-facto-Standard, aber sein Schöpfer Stephen Colebourne entwarf java.time als offiziellen Ersatz, basierend auf den Erfahrungen mit Joda-Time und unter Berücksichtigung seiner Mängel. Das java.time-Paket war in JDK 8 enthalten, aber Android erhielt es erst mit API 26.

ThreeTen-Backport ist ein Port von java.time auf Java 7, erstellt vom selben Autor (Stephen Colebourne). Es enthält alle wichtigen Klassen: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP passt diesen Port für Android an, indem es Initialisierung über AssetsManager und Optimierung für mobile Geräte hinzufügt.

Somit ermöglicht ThreeTenABP die Verwendung der modernen Datums-/Zeit-API auf Geräten mit Android 4.0+ (API 14+) ohne auf ein OS-Update warten zu müssen.

ThreeTenABP zu einem Android-Projekt hinzufügen

Das Hinzufügen erfolgt in zwei Schritten: Abhängigkeit in build.gradle (App-Ebene) hinzufügen und in der Application-Klasse initialisieren. Wichtig: ThreeTenABP benötigt compileSdk von mindestens 21 und Gradle-Version von mindestens 4.0.

Die Abhängigkeit wird im Abschnitt dependencies hinzugefügt: implementation "com.jakewharton.threetenabp:threetenabp:1.4.0". Seit der Veröffentlichung von 1.4.0 wurde die Bibliothek nicht aktualisiert, da sie stabil ist und alle notwendigen Fälle abdeckt.

Laut der offiziellen Dokumentation enthält die Bibliothek tzdata in Assets. Wenn die App bereits einen Assets-Ordner mit anderen Dateien hat, koexistiert ThreeTenABP korrekt mit ihnen. Die Größe von tzdata beträgt komprimiert etwa 200 KB.

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

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

ThreeTenABP initialisieren

Bevor Sie eine Klasse aus org.threeten.bp verwenden, muss die Bibliothek initialisiert werden. Die Initialisierung erfolgt einmal in Application.onCreate() durch Aufruf von AndroidThreeTen.init(this).

Die Initialisierung lädt tzdata-Daten aus Assets und konfiguriert die Systemuhr. Ohne Aufruf von init() werfen die now()-Methoden eine IllegalStateException mit der Meldung, dass die Bibliothek nicht initialisiert ist.

Für Tests können Sie AndroidThreeTen.init(applicationContext, zoneId) verwenden — eine Überladung mit expliziter Zeitzonenangabe. Dies ist nützlich für vorhersagbares Testverhalten. Wenn nur eine Basisinitialisierung ohne tzdata benötigt wird, verwenden Sie AndroidThreeTen.initWithoutFiles(context).

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

// Verwendung nach Initialisierung
val today = LocalDate.now()
val now = LocalDateTime.now()

Welche Klassen sind verfügbar?

ThreeTenABP stellt alle wichtigen java.time-Klassen im Paket org.threeten.bp bereit. Die API ist praktisch identisch mit dem originalen java.time, was die Migration bei einem Wechsel zu API 26+ erleichtert.

Hauptklassen:

  • LocalDate — Datum ohne Uhrzeit und Zeitzone
  • LocalTime — Uhrzeit ohne Datum und Zeitzone
  • LocalDateTime — Datum und Uhrzeit ohne Zeitzone
  • ZonedDateTime — Datum und Uhrzeit mit Zeitzone
  • OffsetDateTime — Datum und Uhrzeit mit festem Offset
  • OffsetTime — Uhrzeit mit festem Offset
  • Instant — Zeitpunkt in UTC
  • Duration — zeitbasierte Dauer
  • Period — datumsbasierte Dauer
  • DateTimeFormatter — Formatierung und Analyse
  • ZoneId / ZoneOffset — Zeitzonen

Hilfsklassen werden ebenfalls unterstützt: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Die Zeitzonen sind in der Bibliothek enthalten (IANA tzdata). Die tzdata-Version in ThreeTenABP 1.4.0 entspricht 2021a.

ThreeTenABP vs Desugaring

Ab Android Gradle Plugin 4.0 (2020) und desugar_jdk_libs erhalten Entwickler die Möglichkeit, java.time auf allen Android-Versionen über coreLibraryDesugaring zu verwenden. Desugaring transformiert Bytecode, sodass java.time-Aufrufe auf älteren APIs ohne zusätzliche Bibliotheken funktionieren.

Vorteile von Desugaring: Verwendet das originale java.time-Paket (nicht org.threeten.bp), keine Initialisierung erforderlich, vollständige Integration mit Android Studio. Nachteile: Erfordert AGP 4.0+, verlängert die Build-Zeit, die APK-Größe kann um 2-3 MB steigen.

ThreeTenABP bleibt die beste Wahl für Legacy-Projekte, die AGP nicht auf 4.0+ aktualisieren können, oder wenn die APK-Größe kritisch ist. ThreeTenABP ist auch einfacher einzurichten — nur eine Abhängigkeit und eine Zeile Initialisierung. Laut Stack Overflow (2024) verwenden etwa 30% der Projekte mit minSdk < 26 immer noch ThreeTenABP anstelle von Desugaring.

Anwendungsbeispiele

Das erste Beispiel demonstriert die Arbeit mit Daten unter Verwendung von ThreeTenABP. Die API ist identisch mit java.time, aber die Importe stammen aus org.threeten.bp. Dies ermöglicht das Schreiben von Code, der nach der Migration nur den Austausch der Importe erfordert.

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

Das zweite Beispiel zeigt die Datumsformatierung. DateTimeFormatter aus org.threeten.bp funktioniert genauso wie 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)
}

Das dritte Beispiel demonstriert die Arbeit mit ZonedDateTime und die Konvertierung zwischen Zeitzonen in ThreeTenABP.

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

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

Migration von ThreeTenABP zu integriertem java.time

Wenn Sie minSdk auf 26 erhöhen, können Sie ThreeTenABP entfernen und auf integriertes java.time umsteigen. Der Migrationsprozess umfasst mehrere Schritte und erfordert gründliche Tests.

Der erste Schritt ist der Austausch der Importe. Importe von org.threeten.bp werden zu java.time geändert. In den meisten Fällen stimmen die Klassennamen überein: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. Die Ausnahme ist DateTimeFormatter — in ThreeTenABP befindet es sich in org.threeten.bp.format, in java.time in java.time.format.

Der zweite Schritt ist das Entfernen der Initialisierung. Die Zeile AndroidThreeTen.init(this) wird nicht mehr benötigt, da java.time in das Android SDK integriert ist. Entfernen Sie den Aufruf aus Application.onCreate() und die Abhängigkeit aus build.gradle.

Der dritte Schritt ist das Ersetzen der Abhängigkeit durch Desugaring, wenn minSdk unter 26 bleibt. Fügen Sie isCoreLibraryDesugaringEnabled = true in compileOptions und die Abhängigkeit desugar_jdk_libs hinzu. Dies stellt sicher, dass java.time auf älteren APIs ohne ThreeTenABP funktioniert. Laut Google I/O (2023) ist Desugaring der bevorzugte Ansatz für neue Projekte.

groovy
// build.gradle — ThreeTenABP durch Desugaring ersetzen
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Entfernen: implementation "com.jakewharton.threetenabp:threetenabp:1.4.0"
    // Hinzufügen:
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

// AndroidThreeTen.init(this) aus Application entfernen

Häufig gestellte Fragen

Kann ThreeTenABP zusammen mit Desugaring verwendet werden?

Technisch gesehen — ja, aber es macht keinen Sinn. Wenn Desugaring verwendet wird, ist integriertes java.time bereits verfügbar. Die Verwendung beider Bibliotheken führt zu Code-Duplizierung und erhöhter APK-Größe. Wählen Sie einen Ansatz für Ihr Projekt.

Warum benötigt ThreeTenABP eine Initialisierung in Application?

Die Initialisierung lädt die IANA Time Zone Database aus Assets in den Speicher. Auf Standard-JDK ist tzdata über Classpath verfügbar, aber Android verwendet AssetManager. Die init()-Methode kopiert Daten in das Systemverzeichnis und macht sie für ZoneId verfügbar.

Welche Android-Versionen unterstützt ThreeTenABP?

ThreeTenABP unterstützt API 14+ (Android 4.0 Ice Cream Sandwich und höher). Java 8-Kompatibilität ist erforderlich (sourceCompatibility und targetCompatibility in compileOptions). Auf API 26+ wird die Bibliothek nicht benötigt — verwenden Sie integriertes java.time.

Wie aktualisiert man Zeitzonen in ThreeTenABP?

Die Zeitzonen sind in der Bibliothek enthalten. Version 1.4.0 enthält tzdata 2021a. Zum Aktualisieren müssen Sie die ThreeTenABP-Version aktualisieren oder tzdata manuell in Assets ersetzen. Die neuesten tzdata-Versionen können aus dem IANA-Repository oder über ThreeTen-Backport bezogen werden.

Wie testet man Code mit ThreeTenABP?

Für Unit-Tests verwenden Sie AndroidThreeTen.init(context, zoneId) mit expliziter Zonenangabe. Für Robolectric-Tests — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). Für reine JVM-Tests ohne Android — verwenden Sie ThreeTen-Backport direkt ohne ThreeTenABP.

Zusammenfassung

  • ThreeTenABP ist ein Android-Adapter für ThreeTen-Backport, der die java.time-API auf Geräten mit Android < 8 (API < 26) bereitstellt.
  • Wird über Gradle-Abhängigkeit com.jakewharton.threetenabp:threetenabp:1.4.0 hinzugefügt und erfordert AndroidThreeTen.init(this) in Application.onCreate().
  • Verwendet das Paket org.threeten.bp statt java.time — die API ist praktisch identisch, was die Migration zu API 26+ vereinfacht.
  • Hauptklassen: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter — alle in ThreeTenABP verfügbar.
  • Mit dem Aufkommen von Desugaring (AGP 4.0+) ist ThreeTenABP optional geworden, bleibt aber für Legacy-Projekte oder bei APK-Größenbeschränkungen relevant.
  • Bei der Migration zu java.time ersetzen Sie Importe org.threeten.bp → java.time, entfernen AndroidThreeTen.init() und ersetzen die Abhängigkeit durch desugar_jdk_libs.
  • Für Tests verwenden Sie AndroidThreeTen.init(context, zoneId) mit expliziter Zonenangabe für vorhersagbares Verhalten.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch