ThreeTenABP: mi ez, java.time könyvtár Androidhoz

Szerző: IT Sectr Megjelenés: 2026-07-14 Olvasási idő: 11 perc

ThreeTenABP — adapter könyvtár Androidhoz, amely java.time API-t (org.threeten.bp csomag) biztosít Android 8 alatti (API < 26) eszközökön. A specifikáció szerint Jake Wharton (GitHub, 2023), a könyvtár egy burkoló a ThreeTen-Backport projekt fölött, amely Androidhoz van adaptálva az erőforrás-optimalizálás és a tzdata AssetManageren keresztüli támogatásának figyelembevételével.

Főbb pontok

  • ThreeTenABP — Android adapter a ThreeTen-Backport számára, amely java.time-ot biztosít API < 26 esetén.
  • Gradlen keresztül csatlakozik: implementation „com.jakewharton.threetenabp:threetenabp:1.4.x”.
  • Inicializálást igényel az Application.onCreate()-ban AndroidThreeTen.init(this) segítségével.
  • A java.time helyett az org.threeten.bp csomagot használja — az API gyakorlatilag azonos.
  • A desugaring (AGP 4.0+) megjelenésével a ThreeTenABP opcionálissá vált és legacy projektekhez használják.

Mi az a ThreeTenABP?

ThreeTenABP (ThreeTen Android Backport) — Jake Wharton által létrehozott könyvtár a Java 8 dátum/idő API használatára régebbi Android verziókon. Ez egy adapter a ThreeTen-Backport projekthez, amely a java.time-ot (JSR-310) portolja Java 7-re és Android API < 26-ra.

A fő probléma, amit a könyvtár megold: az Android 8-as verzióig (API 26) nem tartalmazta a java.time-ot a standard csomagban. A fejlesztők kényszerültek java.util.Date/Calendar használatára vagy Joda-Time hozzáadására. A ThreeTenABP ugyanazt a modern API-t nyújtja, mint a beépített java.time, de az org.threeten.bp csomagon keresztül.

A GitHub repozitórium (2023) szerint a könyvtár optimalizált Androidra: a tzdata adatok (IANA Time Zone Database) az assets mappában tárolódnak és AssetManageren keresztül töltődnek be, nem classpath-en keresztül, mint asztali gépen. Ez csökkenti az APK méretét és gyorsítja a betöltést.

Utolsó stabil verzió — 1.4.0 (2021. augusztus). A könyvtár támogatási módban van, mivel a desugaring széles körű elterjedésével csökken az iránta való igény, de továbbra is releváns a minimális API < 26 projektek számára.

Miért van szükség java.time backportra?

A java.time megjelenése (Java 8, 2014) előtt a fejlesztők java.util.Date és java.util.Calendar osztályokat használtak. Ezek az osztályok komoly hiányosságokkal rendelkeznek: a Date módosítható, a Calendar nem intuitív konstansokat használ (Calendar.JANUARY = 0), mindkét osztály nem thread-safe és hajlamos a hibára az időzónákkal való munka során.

A Joda-Time volt a de facto standard Java 8 előtt, de alkotója, Stephen Colebourne a java.time-ot tervezte meg hivatalos helyettesítőként, a Joda-Time tapasztalataira építve és annak hiányosságait figyelembe véve. A java.time csomag részévé vált a JDK 8-nak, de az Android csak API 26-tól kapta meg.

ThreeTen-Backport — a java.time portolása Java 7-re, amelyet ugyanaz a szerző (Stephen Colebourne) készített. Tartalmazza az összes fő osztályt: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. A ThreeTenABP ezt a portot adaptálja Androidra, hozzáadva az inicializálást AssetsManageren keresztül és optimalizálást mobil eszközökhöz.

Így a ThreeTenABP lehetővé teszi a modern dátum/idő API használatát Android 4.0+ (API 14+) eszközökön anélkül, hogy meg kellene várni az operációs rendszer frissítését.

ThreeTenABP csatlakoztatása Android projektben

A csatlakoztatás két lépésben történik: függőség hozzáadása a build.gradle-ben (app-level) és inicializálás az Application osztályban. Fontos: A ThreeTenABP compileSdk-t legalább 21 és Gradle verziót legalább 4.0 követel meg.

A függőség a dependencies szekcióban kerül hozzáadásra: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”. Az 1.4.0 kiadás óta a könyvtár nem frissült, mert stabil és lefedi az összes szükséges esetet.

A hivatalos dokumentáció szerint a könyvtár tartalmazza a tzdata-t az assets mappában. Ha az alkalmazásnak már van assets mappája más fájlokkal, a ThreeTenABP helyesen együtt működik velük. A tzdata mérete körülbelül 200 KB tömörített formában.

groovy
// build.gradle (alkalmazás szint)
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

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

ThreeTenABP inicializálása

Mielőtt bármely osztályt használná az org.threeten.bp-ből, inicializálni kell a könyvtárat. Az inicializálás egyszer történik az Application.onCreate()-ban az AndroidThreeTen.init(this) meghívásával.

Az inicializálás betölti a tzdata adatokat az assets-ből és beállítja a rendszerórát. Az init() meghívása nélkül a now() metódusok IllegalStateException kivételt dobnak azzal az üzenettel, hogy a könyvtár nincs inicializálva.

Tesztekhez használható az AndroidThreeTen.init(applicationContext, zoneId) — túlterhelés az időzóna explicit megadásával. Ez hasznos a tesztek kiszámítható viselkedéséhez. Ha csak alap inicializálásra van szükség tzdata nélkül — használja a AndroidThreeTen.initWithoutFiles(context) függvényt.

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

// Használat inicializálás után
val today = LocalDate.now()
val now = LocalDateTime.now()

Milyen osztályok érhetők el?

A ThreeTenABP biztosítja az összes fő java.time osztályt, de az org.threeten.bp csomagban. Az API gyakorlatilag azonos az eredeti java.time-val, ami megkönnyíti a migrációt API 26+-ra való áttéréskor.

Fő osztályok:

  • LocalDate — dátum idő és időzóna nélkül
  • LocalTime — idő dátum és időzóna nélkül
  • LocalDateTime — dátum és idő időzóna nélkül
  • ZonedDateTime — dátum és idő időzónával
  • OffsetDateTime — dátum és idő rögzített eltolással
  • OffsetTime — idő rögzített eltolással
  • Instant — időpillanat UTC-ben
  • Duration — time-based időtartam
  • Period — date-based periódus
  • DateTimeFormatter — formázás és elemzés
  • ZoneId / ZoneOffset — időzónák

ThreeTenABP vs desugaring

Az Android Gradle Plugin 4.0 (2020) és a desugar_jdk_libs megjelenésétől a fejlesztők lehetőséget kaptak a java.time használatára az Android minden verzióján a coreLibraryDesugaring segítségével. A desugaring átalakítja a bájtkódot úgy, hogy a java.time hívások működjenek a régi API-ken többletkönyvtárak nélkül.

A desugaring előnyei: az eredeti java.time csomagot használja (nem org.threeten.bp), nem igényel inicializálást, teljes integráció az Android Studio-val. Hátrányok: AGP 4.0+ szükséges, növeli a fordítási időt, az APK mérete 2-3 MB-tal nőhet.

A ThreeTenABP továbbra is a legjobb választás azon legacy projektek számára, amelyek nem tudják frissíteni az AGP-t 4.0+-ra, vagy ahol az APK mérete kritikus. A ThreeTenABP beállítása is egyszerűbb — egy függőség és egy sor inicializálás elegendő. A Stack Overflow (2024) szerint a minSdk < 26 projektek körülbelül 30%-a még mindig ThreeTenABP-t használ desugaring helyett.

Használati példák

Első példa — munka dátumokkal ThreeTenABP-n keresztül. Az API megegyezik a java.time-val, de az importok az org.threeten.bp-ből származnak. Ez lehetővé teszi olyan kód írását, amely migráció után csak az importok cseréjét igényli.

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

Második példa — dátum formázása. Az org.threeten.bp-ből származó DateTimeFormatter ugyanúgy működik, mint a java.time-ban.

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

Harmadik példa — munka ZonedDateTime-val és konverzió időzónák között ThreeTenABP-ben.

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

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

Migráció ThreeTenABP-ről beépített java.time-ra

A minSdk 26-ra emelésekor el lehet hagyni a ThreeTenABP-t áttérni a beépített java.time-ra. A migrációs folyamat több lépésből áll és alapos tesztelést igényel.

Első lépés — importok cseréje. Az org.threeten.bp importok java.time-ra változnak. A legtöbb esetben az osztálynevek megegyeznek: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. Kivétel a DateTimeFormatter — ThreeTenABP-ben org.threeten.bp.format-ban, java.time-ban java.time.format-ban van.

Második lépés — inicializálás eltávolítása. A AndroidThreeTen.init(this) sorra már nincs szükség, mert a java.time be van építve az Android SDK-ba. Távolítsa el a hívást az Application.onCreate()-ból és a függőséget a build.gradle-ből.

Harmadik lépés — a függőség cseréje desugaringre, ha a minSdk 26 alatt marad. Adja hozzá az isCoreLibraryDesugaringEnabled = true értéket a compileOptions-ban és a desugar_jdk_libs függőséget. Ez biztosítja a java.time működését régi API-ken ThreeTenABP nélkül. A Google I/O (2023) szerint a desugaring az előnyben részesített módszer új projektekhez.

groovy
// build.gradle — ThreeTenABP cseréje desugaringre
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Távolítás: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”
    // Hozzáadás:
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

// AndroidThreeTen.init(this) eltávolítása az Application-ből

Gyakran ismételt kérdések

Használható a ThreeTenABP együtt a desugaringgel?

Technikailag — igen, de nincs értelme. Ha desugaringet használ, a beépített java.time már elérhető. Mindkét könyvtár használata kódduplikációhoz és az APK méret növekedéséhez vezet. Válasszon egy megközelítést a projekthez.

Miért igényel inicializálást az Application-ben a ThreeTenABP?

Az inicializálás betölti az IANA Time Zone Database adatokat az assets-ből a memóriába. Standard JDK-n a tzdata classpath-en keresztül érhető el, de Android AssetManager-t használ. Az init() metódus másolja az adatokat a rendszerkönyvtárba, elérhetővé téve azokat a ZoneId számára.

Milyen Android verziókat támogat a ThreeTenABP?

A ThreeTenABP API 14+ (Android 4.0 Ice Cream Sandwich és újabb) verziókat támogat. Használathoz Java 8 compatibility szükséges (sourceCompatibility és targetCompatibility a compileOptions-ban). API 26+ esetén a könyvtár nem szükséges — használja a beépített java.time-ot.

Hogyan frissíthetők az időzónák a ThreeTenABP-ben?

Az időzónák a könyvtárral együtt kerülnek szállításra. Az 1.4.0 verzió a tzdata 2021a-t tartalmazza. Frissítéshez frissíteni kell a ThreeTenABP verziót vagy kézzel cserélni a tzdata-t az assets mappában. A tzdata legújabb verziói az IANA repozitóriumból vagy ThreeTen-Backporton keresztül szerezhetők be.

Hogyan tesztelhető a kód ThreeTenABP-vel?

Unit tesztekhez használja az AndroidThreeTen.init(context, zoneId) függvényt a zóna explicit megadásával. Robolectric tesztekhez — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). Tiszta JVM tesztekhez Android nélkül — használja közvetlenül a ThreeTen-Backport-ot ThreeTenABP nélkül.

Összefoglaló

  • ThreeTenABP — Android adapter a ThreeTen-Backport számára, amely java.time API-t biztosít Android < 8 (API < 26) eszközökön.
  • Gradle függőséggel csatlakozik com.jakewharton.threetenabp:threetenabp:1.4.0 és inicializálást igényel AndroidThreeTen.init(this) az Application.onCreate()-ban.
  • Az org.threeten.bp csomagot használja java.time helyett — az API gyakorlatilag azonos, ami megkönnyíti a migrációt API 26+-ra.
  • Fő osztályok: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter — mind elérhető a ThreeTenABP-ben.
  • A desugaring (AGP 4.0+) megjelenésével a ThreeTenABP opcionálissá vált, de továbbra is releváns legacy projektekhez vagy APK méretkorlátok esetén.
  • Java.time-ra való migrációkor cserélje az importokat org.threeten.bp → java.time, távolítsa el az AndroidThreeTen.init()-t és cserélje a függőséget desugar_jdk_libs-re.
  • Teszthez használja az AndroidThreeTen.init(context, zoneId) függvényt a zóna explicit megadásával a kiszámítható viselkedés érdekében.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is