ThreeTenABP: co to je, knihovna java.time pro Android

Autor: IT Sectr Publikováno: 2026-07-14 Doba čtení: 11 min

ThreeTenABP — adaptérová knihovna pro Android, poskytující API java.time (balíček org.threeten.bp) na zařízeních s Androidem pod 8 (API < 26). Podle specifikace Jake Wharton (GitHub, 2023) je knihovna obalem projektu ThreeTen-Backport, přizpůsobeným pro Android s ohledem na optimalizaci zdrojů a podporu tzdata prostřednictvím AssetManager.

Hlavní body

  • ThreeTenABP — Android adaptér pro ThreeTen-Backport, poskytující java.time na API < 26.
  • Připojuje se přes Gradle: implementation „com.jakewharton.threetenabp:threetenabp:1.4.x”.
  • Vyžaduje inicializaci v Application.onCreate() prostřednictvím AndroidThreeTen.init(this).
  • Používá balíček org.threeten.bp místo java.time — API je prakticky identické.
  • S příchodem desugaring (AGP 4.0+) se ThreeTenABP stal volitelným a používá se pro legacy projekty.

Co je ThreeTenABP?

ThreeTenABP (ThreeTen Android Backport) — knihovna vytvořená Jakem Whartonem pro použití Java 8 API data/času na starších verzích Androidu. Jedná se o adaptér projektu ThreeTen-Backport, který portuje java.time (JSR-310) na Java 7 a Android API < 26.

Hlavní problém, který knihovna řeší: Android do verze 8 (API 26) nezahrnoval java.time ve standardní dodávce. Vývojáři byli nuceni používat java.util.Date/Calendar nebo přidávat Joda-Time. ThreeTenABP poskytuje stejné moderní API jako vestavěný java.time, ale prostřednictvím balíčku org.threeten.bp.

Podle GitHub repozitáře (2023) je knihovna optimalizována pro Android: data tzdata (IANA Time Zone Database) jsou uložena v assets a načítána přes AssetManager, nikoli přes classpath jako na desktopu. To snižuje velikost APK a urychluje načítání.

Poslední stabilní verze — 1.4.0 (srpen 2021). Knihovna je v režimu podpory, protože s rozšířením desugaring potřeba po ní klesá, ale zůstává relevantní pro projekty s minimálním API < 26.

Proč je potřeba backport java.time?

Před příchodem java.time v Java 8 (2014) vývojáři používali java.util.Date a java.util.Calendar. Tyto třídy mají vážné nedostatky: Date je mutabilní, Calendar používá neintuitivní konstanty (Calendar.JANUARY = 0), obě třídy nejsou thread-safe a jsou náchylné k chybám při práci s časovými pásmy.

Joda-Time byla de facto standardem před Java 8, ale její tvůrce Stephen Colebourne navrhl java.time jako oficiální náhradu, založenou na zkušenostech s Joda-Time a zohledňující její nedostatky. Balíček java.time se stal součástí JDK 8, ale Android ho nezískal až do API 26.

ThreeTen-Backport — port java.time na Java 7, vytvořený stejným autorem (Stephen Colebourne). Zahrnuje všechny hlavní třídy: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP tento port přizpůsobuje pro Android, přidává inicializaci přes AssetsManager a optimalizaci pro mobilní zařízení.

ThreeTenABP tedy umožňuje používat moderní API data/času na zařízeních s Android 4.0+ (API 14+) bez čekání na aktualizaci OS.

Připojení ThreeTenABP v Android projektu

Připojení se provádí ve dvou krocích: přidání závislosti do build.gradle (app-level) a inicializace v třídě Application. Důležité: ThreeTenABP vyžaduje compileSdk ne nižší než 21 a Gradle verzi ne nižší než 4.0.

Závislost se přidává do sekce dependencies: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”. Od vydání 1.4.0 knihovna nebyla aktualizována, protože je stabilní a pokrývá všechny potřebné případy.

Podle oficiální dokumentace knihovna obsahuje tzdata v assets. Pokud aplikace již má složku assets s jinými soubory, ThreeTenABP s nimi korektně koexistuje. Velikost tzdata je přibližně 200 KB v komprimované podobě.

groovy
// build.gradle (úroveň aplikace)
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

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

Inicializace ThreeTenABP

Před použitím jakékoli třídy z org.threeten.bp je třeba knihovnu inicializovat. Inicializace se provádí jednou v Application.onCreate() voláním AndroidThreeTen.init(this).

Inicializace načítá data tzdata z assets a konfiguruje systémové hodiny. Bez volání init() budou metody now() vyhazovat výjimku IllegalStateException s oznámením, že knihovna není inicializována.

Pro testy lze použít AndroidThreeTen.init(applicationContext, zoneId) — přetížení s explicitním určením časového pásma. To je užitečné pro předvídatelné chování testů. Pokud je potřeba pouze základní inicializace bez tzdata — použijte AndroidThreeTen.initWithoutFiles(context).

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

// Použití po inicializaci
val today = LocalDate.now()
val now = LocalDateTime.now()

Jaké třídy jsou dostupné?

ThreeTenABP poskytuje všechny hlavní třídy java.time, ale v balíčku org.threeten.bp. API je prakticky identické s původním java.time, což usnadňuje migraci při přechodu na API 26+.

Hlavní třídy:

  • LocalDate — datum bez času a časového pásma
  • LocalTime — čas bez data a časového pásma
  • LocalDateTime — datum a čas bez časového pásma
  • ZonedDateTime — datum a čas s časovým pásmem
  • OffsetDateTime — datum a čas s pevným posunem
  • OffsetTime — čas s pevným posunem
  • Instant — okamžik v UTC
  • Duration — time-based trvání
  • Period — date-based období
  • DateTimeFormatter — formátování a parsování
  • ZoneId / ZoneOffset — časová pásma

Podporovány jsou také pomocné třídy: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Časová pásma jsou dodávána s knihovnou (IANA tzdata). Verze tzdata v ThreeTenABP 1.4.0 odpovídá 2021a.

ThreeTenABP vs desugaring

Od Android Gradle Plugin 4.0 (2020) a desugar_jdk_libs získali vývojáři možnost používat java.time na všech verzích Androidu prostřednictvím coreLibraryDesugaring. Desugaring transformuje bytecode tak, že volání java.time fungují na starých API bez dalších knihoven.

Výhody desugaring: používá se původní balíček java.time (ne org.threeten.bp), nevyžaduje inicializaci, plná integrace s Android Studio. Nevýhody: vyžaduje AGP 4.0+, přidává čas sestavení, velikost APK může vzrůst o 2-3 MB.

ThreeTenABP zůstává nejlepší volbou pro legacy projekty, které nemohou aktualizovat AGP na 4.0+, nebo kde je velikost APK kritická. ThreeTenABP je také jednodušší na nastavení — jedna závislost a jeden řádek inicializace stačí. Podle Stack Overflow (2024) asi 30 % projektů s minSdk < 26 stále používá ThreeTenABP místo desugaring.

Příklady použití

První příklad — práce s daty přes ThreeTenABP. API je identické s java.time, ale importy pocházejí z org.threeten.bp. To umožňuje psát kód, který po migraci vyžaduje pouze výměnu importů.

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

Druhý příklad — formátování data. DateTimeFormatter z org.threeten.bp funguje stejně jako v 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)
}

Třetí příklad — práce s ZonedDateTime a konverze mezi časovými pásmy v ThreeTenABP.

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

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

Migrace z ThreeTenABP na vestavěný java.time

Při zvýšení minSdk na 26 lze opustit ThreeTenABP a přejít na vestavěný java.time. Proces migrace zahrnuje několik kroků a vyžaduje důkladné testování.

První krok — výměna importů. Importy org.threeten.bp se mění na java.time. Ve většině případů se názvy tříd shodují: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. Výjimkou je DateTimeFormatter — v ThreeTenABP je v org.threeten.bp.format, v java.time — v java.time.format.

Druhý krok — odstranění inicializace. Řádek AndroidThreeTen.init(this) již není potřeba, protože java.time je vestavěn v Android SDK. Odstraňte volání z Application.onCreate() a závislost z build.gradle.

Třetí krok — nahrazení závislosti desugaringem, pokud minSdk zůstává pod 26. Přidejte isCoreLibraryDesugaringEnabled = true v compileOptions a závislost desugar_jdk_libs. To zajistí fungování java.time na starých API bez ThreeTenABP. Podle Google I/O (2023) je desugaring preferovaným způsobem pro nové projekty.

groovy
// build.gradle — nahraďte ThreeTenABP desugaringem
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Odstraňte: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”
    // Přidejte:
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

// Odstraňte AndroidThreeTen.init(this) z Application

Často kladené otázky

Lze ThreeTenABP používat společně s desugaringem?

Technicky — ano, ale nemá to smysl. Pokud se používá desugaring, vestavěný java.time je již dostupný. Použití obou knihoven povede k duplicitě kódu a zvýšení velikosti APK. Vyberte jeden přístup pro projekt.

Proč ThreeTenABP vyžaduje inicializaci v Application?

Inicializace načítá data IANA Time Zone Database z assets do paměti. Na standardním JDK je tzdata dostupná přes classpath, ale Android používá AssetManager. Metoda init() kopíruje data do systémového adresáře, čímž je zpřístupňuje pro ZoneId.

Jaké verze Androidu ThreeTenABP podporuje?

ThreeTenABP podporuje API 14+ (Android 4.0 Ice Cream Sandwich a vyšší). Pro použití je vyžadována Java 8 compatibility (sourceCompatibility a targetCompatibility v compileOptions). Na API 26+ knihovna není potřeba — použijte vestavěný java.time.

Jak aktualizovat časová pásma v ThreeTenABP?

Časová pásma jsou dodávána s knihovnou. Verze 1.4.0 obsahuje tzdata 2021a. Pro aktualizaci je třeba aktualizovat verzi ThreeTenABP nebo ručně nahradit tzdata v assets. Nejnovější verze tzdata lze získat z repozitáře IANA nebo přes ThreeTen-Backport.

Jak testovat kód s ThreeTenABP?

Pro unit testy použijte AndroidThreeTen.init(context, zoneId) s explicitním určením zóny. Pro Robolectric testy — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). Pro čisté JVM testy bez Androidu — použijte přímo ThreeTen-Backport bez ThreeTenABP.

Shrnutí

  • ThreeTenABP — Android adaptér pro ThreeTen-Backport, poskytující API java.time na zařízeních s Android < 8 (API < 26).
  • Připojuje se přes Gradle závislost com.jakewharton.threetenabp:threetenabp:1.4.0 a vyžaduje inicializaci AndroidThreeTen.init(this) v Application.onCreate().
  • Používá balíček org.threeten.bp místo java.time — API je prakticky identické, což usnadňuje migraci na API 26+.
  • Hlavní třídy: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter — všechny dostupné v ThreeTenABP.
  • S příchodem desugaring (AGP 4.0+) se ThreeTenABP stal volitelným, ale zůstává relevantní pro legacy projekty nebo při omezení velikosti APK.
  • Při migraci na java-time nahraďte importy org.threeten.bp → java.time, odstraňte AndroidThreeTen.init() a nahraďte závislost desugar_jdk_libs.
  • Pro testování použijte AndroidThreeTen.init(context, zoneId) s explicitním určením zóny pro předvídatelné chování.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také