ThreeTenABP: шта је то, библиотека јава.тиме за Андроид

Аутор: IT Sectr Објављено: 2026-07-14 Време читања: 11 мин

ThreeTenABP — библиотека-адаптер за Андроид, која пружа API java.time (пакет org.threeten.bp) на уређајима са Андроидом испод 8 (API < 26). Према спецификацији Jake Wharton (GitHub, 2023), библиотека је омотач пројекта ThreeTen-Backport, прилагођен за Андроид са оптимизацијом ресурса и подршком за tzdata преко AssetManager-а.

Главне тачке

  • ThreeTenABP — Андроид адаптер за ThreeTen-Backport, који пружа java.time на API < 26.
  • Повезује се преко Gradle-а: implementation „com.jakewharton.threetenabp:threetenabp:1.4.x”.
  • Захтева иницијализацију у Application.onCreate() преко AndroidThreeTen.init(this).
  • Користи пакет org.threeten.bp уместо java.time — API је практично идентичан.
  • Са појавом desugaring-а (AGP 4.0+) ThreeTenABP је постао опциони и користи се за legacy пројекте.

Шта је ThreeTenABP?

ThreeTenABP (ThreeTen Android Backport) — библиотека коју је креирао Jake Wharton за коришћење API-ја за датум/време Java 8 на старијим верзијама Андроида. Она је адаптер за пројекат ThreeTen-Backport, који преноси java.time (JSR-310) на Java 7 и Android API < 26.

Главни проблем који библиотека решава: Андроид до верзије 8 (API 26) није укључивао java.time у стандардни пакет. Програмери су били принуђени да користе java.util.Date/Calendar или додају Joda-Time. ThreeTenABP пружа исти модерни API као уграђени java.time, али кроз пакет org.threeten.bp.

Према GitHub репозиторијуму (2023), библиотека је оптимизована за Андроид: tzdata подаци (IANA Time Zone Database) се чувају у assets-у и учитавају преко AssetManager-а, а не преко classpath-а као на десктопу. Ово смањује величину APK-а и убрзава учитавање.

Последња стабилна верзија — 1.4.0 (август 2021). Библиотека је у режиму подршке, јер са широким ширењем desugaring-а потреба за њом опада, али остаје актуелна за пројекте са минималним API < 26.

Зашто је потребан backport java.time?

Пре појаве java.time у Java 8 (2014), програмери су користили java.util.Date и java.util.Calendar. Ове класе имају озбиљне недостатке: Date је мутабилан, Calendar користи неинтуитивне константе (Calendar.JANUARY = 0), обе класе нису thread-safe и склоне су грешкама при раду са временским зонама.

Joda-Time је био de facto стандард пре Java 8, али њен творац Stephen Colebourne је дизајнирао java.time као званичну замену, засновану на искуству Joda-Time и узимајући у обзир њене недостатке. Пакет java.time је ушао у JDK 8, али Андроид га није добио до API 26.

ThreeTen-Backport — порт java.time на Java 7, који је креирао исти аутор (Stephen Colebourne). Укључује све главне класе: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP прилагођава овај порт за Андроид, додајући иницијализацију преко AssetsManager-а и оптимизацију за мобилне уређаје.

Дакле, ThreeTenABP омогућава коришћење модерног API-ја за датум/време на уређајима са Андроид 4.0+ (API 14+) без чекања на ажурирање оперативног система.

Повезивање ThreeTenABP у Андроид пројекту

Повезивање се врши у два корака: додавање зависности у build.gradle (app-level) и иницијализација у Application класи. Важно: ThreeTenABP захтева compileSdk не мањи од 21 и Gradle верзију не мању од 4.0.

Зависност се додаје у одељак dependencies: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”. Од издања 1.4.0 библиотека није ажурирана, јер је стабилна и покрива све потребне случајеве.

Према званичној документацији, библиотека укључује tzdata у assets-у. Ако апликација већ има фасциклу assets са другим датотекама, ThreeTenABP коректно коегзистира са њима. Величина tzdata је око 200 KB у компресованом облику.

groovy
// build.gradle (ниво апликације)
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

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

Иницијализација ThreeTenABP

Пре коришћења било које класе из org.threeten.bp потребно је иницијализовати библиотеку. Иницијализација се врши једном у Application.onCreate() преко позива AndroidThreeTen.init(this).

Иницијализација учитава tzdata податке из assets-а и подешава системски сат. Без позива init() методе now() ће бацати изузетак IllegalStateException са поруком да библиотека није иницијализована.

За тестове се може користити AndroidThreeTen.init(applicationContext, zoneId) — преоптерећење са експлицитним навођењем временске зоне. Ово је корисно за предвидљиво понашање тестова. Ако је потребна само основна иницијализација без tzdata — користите AndroidThreeTen.initWithoutFiles(context).

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

// Коришћење након иницијализације
val today = LocalDate.now()
val now = LocalDateTime.now()

Које класе су доступне?

ThreeTenABP пружа све главне класе java.time, али у пакету org.threeten.bp. API је практично идентичан оригиналном java.time, што олакшава миграцију при преласку на API 26+.

Главне класе:

  • LocalDate — датум без времена и временске зоне
  • LocalTime — време без датума и временске зоне
  • LocalDateTime — датум и време без временске зоне
  • ZonedDateTime — датум и време са временском зоном
  • OffsetDateTime — датум и време са фиксним померајем
  • OffsetTime — време са фиксним померајем
  • Instant — тренутак времена у UTC-у
  • Duration — time-based трајање
  • Period — date-based период
  • DateTimeFormatter — форматирање и парсирање
  • ZoneId / ZoneOffset — временске зоне

Подржане су и помоћне класе: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Временске зоне се испоручују са библиотеком (IANA tzdata). Верзија tzdata у ThreeTenABP 1.4.0 одговара 2021a.

ThreeTenABP против desugaring

Од Android Gradle Plugin 4.0 (2020) и desugar_jdk_libs, програмери су добили могућност коришћења java.time на свим верзијама Андроида преко coreLibraryDesugaring. Desugaring трансформише бајт-код тако да позиви java.time раде на старим API-јима без додатних библиотека.

Предности desugaring-а: користи се оригинални java.time пакет (не org.threeten.bp), није потребна иницијализација, потпуна интеграција са Android Studio. Недостаци: захтева AGP 4.0+, додаје време компајлирања, величина APK-а може порасти за 2-3 MB.

ThreeTenABP остаје најбољи избор за legacy пројекте који не могу ажурирати AGP на 4.0+, или где је величина APK-а критична. Такође, ThreeTenABP је једноставнији за подешавање — довољна је једна зависност и једна линија иницијализације. Према Stack Overflow (2024), око 30% пројеката са minSdk < 26 још увек користи ThreeTenABP уместо desugaring-а.

Примери коришћења

Први пример — рад са датумима преко ThreeTenABP. API је идентичан java.time, али импорти долазе из org.threeten.bp. Ово омогућава писање кода који након миграције захтева само замену импорта.

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

Други пример — форматирање датума. DateTimeFormatter из org.threeten.bp ради исто као у 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)
}

Трећи пример — рад са ZonedDateTime и конверзија између временских зона у ThreeTenABP.

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

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

Миграција са ThreeTenABP на уграђени java.time

При подизању minSdk на 26 може се одустати од ThreeTenABP и прећи на уграђени java.time. Процес миграције укључује неколико корака и захтева пажљиво тестирање.

Први корак — замена импорта. Импорти org.threeten.bp се мењају у java.time. У већини случајева имена класа се поклапају: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. Изузетак је DateTimeFormatter — у ThreeTenABP је у org.threeten.bp.format, у java.time — у java.time.format.

Други корак — уклањање иницијализације. Линија AndroidThreeTen.init(this) више није потребна, јер је java.time уграђен у Андроид SDK. Уклоните позив из Application.onCreate() и зависност из build.gradle-а.

Трећи корак — замена зависности на desugaring, ако minSdk остаје испод 26. Додајте isCoreLibraryDesugaringEnabled = true у compileOptions и зависност desugar_jdk_libs. Ово ће обезбедити рад java.time на старим API-јима без ThreeTenABP. Према Google I/O (2023), desugaring је пожељан метод за нове пројекте.

groovy
// build.gradle — замени ThreeTenABP desugaring-ом
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Уклони: implementation „com.jakewharton.threetenabp:threetenabp:1.4.0”
    // Додај:
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

// Уклони AndroidThreeTen.init(this) из Application

Често постављана питања

Може ли се ThreeTenABP користити заједно са desugaring?

Технички — да, али нема смисла. Ако се користи desugaring, уграђени java.time је већ доступан. Коришћење обе библиотеке довешће до дуплирања кода и повећања величине APK-а. Изаберите један приступ за пројекат.

Зашто ThreeTenABP захтева иницијализацију у Application?

Иницијализација учитава IANA Time Zone Database податке из assets-а у меморију. На стандардном JDK-у tzdata је доступна преко classpath-а, али Андроид користи AssetManager. Метода init() копира податке у системски директоријум, чинећи их доступним за ZoneId.

Које верзије Андроида подржава ThreeTenABP?

ThreeTenABP подржава API 14+ (Android 4.0 Ice Cream Sandwich и новије). За коришћење је потребна Java 8 compatibility (sourceCompatibility и targetCompatibility у compileOptions). На API 26+ библиотека није потребна — користите уграђени java.time.

Како ажурирати временске зоне у ThreeTenABP?

Временске зоне се испоручују са библиотеком. Верзија 1.4.0 укључује tzdata 2021a. За ажурирање потребно је ажурирати верзију ThreeTenABP или ручно заменити tzdata у assets-у. Најновије верзије tzdata могу се добити из IANA репозиторијума или преко ThreeTen-Backport-а.

Како тестирати код са ThreeTenABP?

За јединичне тестове користите AndroidThreeTen.init(context, zoneId) са експлицитним навођењем зоне. За Robolectric тестове — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). За чисте JVM тестове без Андроида — користите ThreeTen-Backport директно без ThreeTenABP.

Закључак

  • ThreeTenABP — Андроид адаптер за ThreeTen-Backport, који пружа API java.time на уређајима са Андроид < 8 (API < 26).
  • Повезује се преко Gradle зависности com.jakewharton.threetenabp:threetenabp:1.4.0 и захтева иницијализацију AndroidThreeTen.init(this) у Application.onCreate().
  • Користи пакет org.threeten.bp уместо java.time — API је практично идентичан, што олакшава миграцију на API 26+.
  • Главне класе: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter — све доступне у ThreeTenABP.
  • Са појавом desugaring-а (AGP 4.0+) ThreeTenABP је постао опциони, али остаје актуелан за legacy пројекте или при ограничењима величине APK-а.
  • При миграцији на java-time, замените импорте org.threeten.bp → java.time, уклоните AndroidThreeTen.init() и замените зависност на desugar_jdk_libs.
  • За тестирање користите AndroidThreeTen.init(context, zoneId) са експлицитним навођењем зоне за предвидљиво понашање.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође