ThreeTenABP: bu nədir, Android üçün java.time kitabxanası

Müəllif: IT Sectr Dərc olunub: 2026-07-14 Oxuma vaxtı: 11 dəq

ThreeTenABP — Android üçün adapter kitabxanası, Android 8-dən aşağı (API < 26) cihazlarda java.time API-ni (org.threeten.bp paketi) təmin edir. Spesifikasiyaya görə Jake Wharton (GitHub, 2023), kitabxana ThreeTen-Backport layihəsi üzərində örtük olub, resurs optimallaşdırması və AssetManager vasitəsilə tzdata dəstəyi nəzərə alınmaqla Android üçün uyğunlaşdırılıb.

Əsas məqamlar

  • ThreeTenABP — ThreeTen-Backport üçün Android adapteri, API < 26-da java.time təmin edir.
  • Gradle vasitəsilə qoşulur: implementation “com.jakewharton.threetenabp:threetenabp:1.4.x”.
  • Application.onCreate() daxilində AndroidThreeTen.init(this) vasitəsilə işə salma tələb edir.
  • java.time əvəzinə org.threeten.bp paketindən istifadə edir — API praktiki olaraq eynidir.
  • Desugaring (AGP 4.0+) yaranması ilə ThreeTenABP isteğe bağlı oldu və legacy layihələr üçün istifadə olunur.

ThreeTenABP nədir?

ThreeTenABP (ThreeTen Android Backport) — Jake Wharton tərəfindən köhnə Android versiyalarında Java 8 tarix/vaxt API-dən istifadə üçün yaradılmış kitabxanadır. ThreeTen-Backport layihəsi üçün adapter olub, java.time (JSR-310) Java 7 və Android API < 26-ya port edir.

Kitabxananın həll etdiyi əsas problem: Android 8-dən (API 26) əvvəlki versiyalar java.time-ı standart tərkibə daxil etmirdi. Tərtibatçılar java.util.Date/Calendar istifadə etməyə və ya Joda-Time qoşmağa məcbur idilər. ThreeTenABP daxili java.time ilə eyni müasir API-ni təmin edir, lakin org.threeten.bp paketi vasitəsilə.

Məlumatlara görə GitHub deposu (2023), kitabxana Android üçün optimallaşdırılıb: tzdata məlumatları (IANA Time Zone Database) assets-də saxlanılır və AssetManager vasitəsilə yüklənir, masaüstü versiyadakı kimi classpath vasitəsilə deyil. Bu APK ölçüsünü azaldır və yükləməni sürətləndirir.

Son sabit versiya — 1.4.0 (avqust 2021). Kitabxana dəstək rejimindədir, çünki desugaring-in geniş yayılması ilə ona ehtiyaz azalır, lakin minimal API < 26 olan layihələr üçün aktual qalır.

Niyə java.time backport lazımdır?

Java 8-də (2014) java.time peyda olmamışdan əvvəl tərtibatçılar java.util.Datejava.util.Calendar istifadə edirdilər. Bu siniflərin ciddi çatışmazlıqları var: Date mutable-dır, Calendar intuitiv olmayan sabitlərdən istifadə edir (Calendar.JANUARY = 0), hər iki sinif thread-safe deyil və saat qurşaqları ilə işləyərkən səhvlərə meyllidir.

Joda-Time Java 8-dən əvvəl de-fakto standart idi, lakin onun yaradıcısı Stephen Colebourne java.time-ı rəsmi əvəzedici kimi dizayn etdi, Joda-Time təcrübəsinə əsaslanaraq və onun çatışmazlıqlarını nəzərə alaraq. java.time paketi JDK 8-ə daxil oldu, lakin Android onu API 26-ya qədər almadı.

ThreeTen-Backport — eyni müəllif (Stephen Colebourne) tərəfindən yaradılmış java.time-ın Java 7-yə portudur. Bütün əsas sinifləri əhatə edir: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP bu portu Android üçün uyğunlaşdırır, AssetsManager vasitəsilə işə salma və mobil cihazlar üçün optimallaşdırma əlavə edir.

Beləliklə, ThreeTenABP Android 4.0+ (API 14+) cihazlarda müasir tarix/vaxt API-dən istifadə etməyə imkan verir, ƏS yeniləməsini gözləmədən.

ThreeTenABP-nin Android layihəsinə qoşulması

Qoşulma iki addımda həyata keçirilir: build.gradle (app-level) faylına asılılıq əlavə etmək və Application sinfində işə salma. Vacib: ThreeTenABP compileSdk 21-dən aşağı olmayan və Gradle versiyası 4.0-dan aşağı olmayan tələb edir.

Asılılıq dependencies bölməsinə əlavə olunur: implementation “com.jakewharton.threetenabp:threetenabp:1.4.0”. 1.4.0 buraxılışından bəri kitabxana yenilənməyib, çünki sabitdir və bütün lazımi halları əhatə edir.

Rəsmi sənədlərə görə ofisial dokumentasiya, kitabxana tzdata-nı assets-də ehtiva edir. Əgər tətbiqdə artıq digər faylları olan assets qovluğu varsa, ThreeTenABP onlarla düzgün şəkildə birgə mövcud olur. Tzdata ölçüsü sıxılmış halda təxminən 200 KB-dır.

groovy
// build.gradle (tətbiq səviyyəsi)
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

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

ThreeTenABP-nin işə salınması

org.threeten.bp-dən hər hansı sinifdən istifadə etməzdən əvvəl kitabxananı işə salmaq lazımdır. İşə salma bir dəfə Application.onCreate() daxilində AndroidThreeTen.init(this) çağırışı vasitəsilə həyata keçirilir.

İşə salma tzdata məlumatlarını assets-dən yükləyir və sistem saatını konfiqurasiya edir. init() çağırışı olmadan now() metodları kitabxananın işə salınmadığı barədə IllegalStateException istisnası qaytaracaq.

Testlər üçün AndroidThreeTen.init(applicationContext, zoneId) — saat qurşağının açıq göstərilməsi ilə overload istifadə oluna bilər. Bu testlərin proqnozlaşdırıla bilən davranışı üçün faydalıdır. Yalnız tzdata olmadan əsas işə salma lazımdırsa — AndroidThreeTen.initWithoutFiles(context) istifadə edin.

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

// İşə salmadan sonra istifadə
val today = LocalDate.now()
val now = LocalDateTime.now()

Hansı siniflər mövcuddur?

ThreeTenABP java.time-ın bütün əsas siniflərini təmin edir, lakin org.threeten.bp paketində. API orijinal java.time ilə praktiki olaraq eynidir, bu da API 26+-ya keçərkən miqrasiyanı asanlaşdırır.

Əsas siniflər:

  • LocalDate — vaxt və saat qurşağı olmadan tarix
  • LocalTime — tarix və saat qurşağı olmadan vaxt
  • LocalDateTime — saat qurşağı olmadan tarix və vaxt
  • ZonedDateTime — saat qurşağı ilə tarix və vaxt
  • OffsetDateTime — sabit yerdəyişmə ilə tarix və vaxt
  • OffsetTime — sabit yerdəyişmə ilə vaxt
  • Instant — UTC-də vaxt anı
  • Duration — time-based müddət
  • Period — date-based müddət
  • DateTimeFormatter — formatlaşdırma və pars etmə
  • ZoneId / ZoneOffset — saat qurşaqları

Köməkçi siniflər də dəstəklənir: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Saat qurşaqları kitabxana ilə birlikdə verilir (IANA tzdata). ThreeTenABP 1.4.0-da tzdata versiyası 2021a-ya uyğundur.

ThreeTenABP vs desugaring

Android Gradle Plugin 4.0 (2020) və desugar_jdk_libs-dən başlayaraq, tərtibatçılar coreLibraryDesugaring vasitəsilə bütün Android versiyalarında java.time istifadə etmək imkanı əldə etdilər. Desugaring bayt kodunu elə transformasiya edir ki, java.time çağırışları əlavə kitabxanalar olmadan köhnə API-lərdə işləyir.

Desugaring-in üstünlükləri: orijinal java.time paketi istifadə olunur (org.threeten.bp yox), işə salma tələb olunmur, Android Studio ilə tam inteqrasiya. Çatışmazlıqları: AGP 4.0+ tələb edir, qurma vaxtını artırır, APK ölçüsü 2-3 MB arta bilər.

ThreeTenABP AGP-ni 4.0+-a yeniləyə bilməyən legacy layihələr və ya APK ölçüsünün kritik olduğu hallar üçün ən yaxşı seçim olaraq qalır. Həmçinin ThreeTenABP quraşdırmada daha sadədir — bir asılılıq və bir sətir işə salma kifayətdir. Stack Overflow (2024) məlumatlarına görə, minSdk < 26 olan layihələrin təxminən 30%-i hələ də desugaring əvəzinə ThreeTenABP istifadə edir.

İstifadə nümunələri

Birinci nümunə — ThreeTenABP vasitəsilə tarixlərlə iş. API java.time ilə eynidir, lakin importlar org.threeten.bp-dən gəlir. Bu, miqrasiyadan sonra yalnız importların dəyişdirilməsini tələb edən kod yazmağa imkan verir.

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

İkinci nümunə — tarixin formatlaşdırılması. org.threeten.bp-dən DateTimeFormatter java.time-dakı kimi işləyir.

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

Üçüncü nümunə — ZonedDateTime ilə iş və ThreeTenABP-də saat qurşaqları arasında konvertasiya.

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

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

ThreeTenABP-dən daxili java.time-a miqrasiya

minSdk 26-ya qaldırıldıqda ThreeTenABP-dən imtina edib daxili java.time-a keçmək olar. Miqrasiya prosesi bir neçə addımı əhatə edir və diqqətli test tələb edir.

Birinci addım — importların dəyişdirilməsi. org.threeten.bp importları java.time ilə əvəz olunur. Əksər hallarda sinif adları uyğundur: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. İstisna DateTimeFormatter-dir — ThreeTenABP-də org.threeten.bp.format, java.time-da isə java.time.format.

İkinci addım — işə salmanın silinməsi. AndroidThreeTen.init(this) sətri artıq lazım deyil, çünki java.time Android SDK-ya daxildir. Application.onCreate() çağırışını və build.gradle-dən asılılığı silin.

Üçüncü addım — minSdk 26-dan aşağı qalırsa, asılılığı desugaring ilə əvəz edin. compileOptions-da isCoreLibraryDesugaringEnabled = true və desugar_jdk_libs asılılığını əlavə edin. Bu, ThreeTenABP olmadan köhnə API-lərdə java.time işini təmin edəcək. Google I/O (2023) məlumatlarına görə, desugaring yeni layihələr üçün üstünlük verilən üsuldur.

groovy
// build.gradle — ThreeTenABP-ni desugaring ilə əvəz et
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Sil: implementation “com.jakewharton.threetenabp:threetenabp:1.4.0”
    // Əlavə et:
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

// Application-dən AndroidThreeTen.init(this) sil

Tez-tez verilən suallar

ThreeTenABP-ni desugaring ilə birlikdə istifadə etmək olar?

Texniki olaraq — bəli, lakin bunun mənası yoxdur. Desugaring istifadə olunursa, daxili java.time artıq mövcuddur. Hər iki kitabxananın istifadəsi kodun təkrarlanmasına və APK ölçüsünün artmasına səbəb olacaq. Layihə üçün bir yanaşma seçin.

Niyə ThreeTenABP Application-da işə salma tələb edir?

İşə salma IANA Time Zone Database məlumatlarını assets-dən yaddaşa yükləyir. Standart JDK-da tzdata classpath vasitəsilə mövcuddur, lakin Android AssetManager istifadə edir. init() metodu məlumatları sistem qovluğuna kopyalayaraq onları ZoneId üçün əlçatan edir.

ThreeTenABP hansı Android versiyalarını dəstəkləyir?

ThreeTenABP API 14+ (Android 4.0 Ice Cream Sandwich və daha yuxarı) dəstəkləyir. İstifadə üçün Java 8 compatibility (compileOptions-da sourceCompatibility və targetCompatibility) tələb olunur. API 26+-da kitabxana lazım deyil — daxili java.time istifadə edin.

ThreeTenABP-də saat qurşaqlarını necə yeniləmək olar?

Saat qurşaqları kitabxana ilə birlikdə verilir. 1.4.0 versiyası tzdata 2021a daxildir. Yeniləmək üçün ThreeTenABP versiyasını yeniləmək və ya assets-də tzdata-nı əl ilə əvəz etmək lazımdır. Tzdata-nın son versiyalarını IANA deposundan və ya ThreeTen-Backport vasitəsilə əldə etmək olar.

ThreeTenABP ilə kodu necə test etmək olar?

Vahid testlər üçün zonanın açıq göstərilməsi ilə AndroidThreeTen.init(context, zoneId) istifadə edin. Robolectric testləri üçün — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). Android olmadan təmiz JVM testləri üçün — ThreeTenABP olmadan birbaşa ThreeTen-Backport istifadə edin.

Nəticə

  • ThreeTenABP — ThreeTen-Backport üçün Android adapteri, Android < 8 (API < 26) cihazlarda java.time API təmin edir.
  • Gradle asılılığı ilə qoşulur com.jakewharton.threetenabp:threetenabp:1.4.0 və Application.onCreate()-də AndroidThreeTen.init(this) işə salma tələb edir.
  • java.time əvəzinə org.threeten.bp paketindən istifadə edir — API praktiki olaraq eynidir, bu da API 26+-ya keçərkən miqrasiyanı asanlaşdırır.
  • Əsas siniflər: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter — hamısı ThreeTenABP-də mövcuddur.
  • Desugaring (AGP 4.0+) yaranması ilə ThreeTenABP isteğe bağlı oldu, lakin legacy layihələr və ya APK ölçüsü məhdudiyyətləri üçün aktual qalır.
  • java.time-a miqrasiya zamanı importları org.threeten.bp → java.time ilə əvəz edin, AndroidThreeTen.init() silin və asılılığı desugar_jdk_libs ilə dəyişdirin.
  • Test üçün proqnozlaşdırıla bilən davranış üçün zonanın açıq göstərilməsi ilə AndroidThreeTen.init(context, zoneId) istifadə edin.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun