ThreeTenABP: what is it, java.time library for Android

Author: IT Sectr Published: 2026-07-14 Reading time: 11 min

ThreeTenABP is an adapter library for Android that provides the java.time API (org.threeten.bp package) on devices with Android below 8 (API < 26). According to the specification by Jake Wharton (GitHub, 2023), the library is a wrapper around the ThreeTen-Backport project, adapted for Android with resource optimization and tzdata support through AssetManager.

Key Takeaways

  • ThreeTenABP is an Android adapter for ThreeTen-Backport, providing java.time on API < 26.
  • Added via Gradle: implementation "com.jakewharton.threetenabp:threetenabp:1.4.x".
  • Requires initialization in Application.onCreate() via AndroidThreeTen.init(this).
  • Uses the org.threeten.bp package instead of java.time — the API is virtually identical.
  • With the advent of desugaring (AGP 4.0+), ThreeTenABP has become optional and is used for legacy projects.

What is ThreeTenABP?

ThreeTenABP (ThreeTen Android Backport) is a library created by Jake Wharton for using the Java 8 date/time API on older Android versions. It is an adapter for the ThreeTen-Backport project, which ports java.time (JSR-310) to Java 7 and Android API < 26.

The main problem the library solves: Android before version 8 (API 26) did not include java.time in the standard distribution. Developers were forced to use java.util.Date/Calendar or add Joda-Time. ThreeTenABP provides the same modern API as built-in java.time, but through the org.threeten.bp package.

According to the GitHub repository (2023), the library is optimized for Android: tzdata (IANA Time Zone Database) is stored in assets and loaded through AssetManager, rather than through classpath as on desktop. This reduces APK size and speeds up loading.

The latest stable version is 1.4.0 (August 2021). The library is in maintenance mode, as with the widespread adoption of desugaring, the need for it is decreasing, but it remains relevant for projects with a minimum API < 26.

Why is a java.time backport needed?

Before java.time was introduced in Java 8 (2014), developers used java.util.Date and java.util.Calendar. These classes have serious drawbacks: Date is mutable, Calendar uses non-intuitive constants (Calendar.JANUARY = 0), both classes are not thread-safe and are prone to errors when working with time zones.

Joda-Time was the de facto standard before Java 8, but its creator Stephen Colebourne designed java.time as the official replacement, based on the experience of Joda-Time and addressing its shortcomings. The java.time package was included in JDK 8, but Android did not receive it until API 26.

ThreeTen-Backport is a port of java.time to Java 7, created by the same author (Stephen Colebourne). It includes all the main classes: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter. ThreeTenABP adapts this port for Android, adding initialization through AssetsManager and optimization for mobile devices.

Thus, ThreeTenABP allows you to use the modern date/time API on devices with Android 4.0+ (API 14+) without waiting for an OS update.

Adding ThreeTenABP to an Android project

Adding the library takes two steps: adding the dependency in build.gradle (app-level) and initializing it in the Application class. Important: ThreeTenABP requires compileSdk of at least 21 and Gradle version of at least 4.0.

The dependency is added in the dependencies section: implementation "com.jakewharton.threetenabp:threetenabp:1.4.0". Since the release of 1.4.0, the library has not been updated, as it is stable and covers all necessary cases.

According to the official documentation, the library includes tzdata in assets. If the app already has an assets folder with other files, ThreeTenABP coexists with them correctly. The tzdata size is about 200 KB compressed.

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

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

Initializing ThreeTenABP

Before using any class from org.threeten.bp, the library must be initialized. Initialization is performed once in Application.onCreate() by calling AndroidThreeTen.init(this).

Initialization loads tzdata from assets and configures the system clock. Without calling init(), the now() methods will throw an IllegalStateException with a message that the library is not initialized.

For testing, you can use AndroidThreeTen.init(applicationContext, zoneId) — an overload with explicit time zone specification. This is useful for predictable test behavior. If only basic initialization without tzdata is needed, use AndroidThreeTen.initWithoutFiles(context).

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

// Usage after initialization
val today = LocalDate.now()
val now = LocalDateTime.now()

What classes are available?

ThreeTenABP provides all the main java.time classes, but in the org.threeten.bp package. The API is virtually identical to the original java.time, making migration easier when transitioning to API 26+.

Main classes:

  • LocalDate — date without time and time zone
  • LocalTime — time without date and time zone
  • LocalDateTime — date and time without time zone
  • ZonedDateTime — date and time with time zone
  • OffsetDateTime — date and time with fixed offset
  • OffsetTime — time with fixed offset
  • Instant — moment in time in UTC
  • Duration — time-based duration
  • Period — date-based duration
  • DateTimeFormatter — formatting and parsing
  • ZoneId / ZoneOffset — time zones

Helper classes are also supported: Clock, DayOfWeek, Month, Year, YearMonth, MonthDay. Time zones are bundled with the library (IANA tzdata). The tzdata version in ThreeTenABP 1.4.0 corresponds to 2021a.

ThreeTenABP vs desugaring

Starting with Android Gradle Plugin 4.0 (2020) and desugar_jdk_libs, developers gained the ability to use java.time on all Android versions through coreLibraryDesugaring. Desugaring transforms bytecode so that java.time calls work on older APIs without additional libraries.

Advantages of desugaring: uses the original java.time package (not org.threeten.bp), no initialization required, full integration with Android Studio. Disadvantages: requires AGP 4.0+, adds build time, APK size may increase by 2-3 MB.

ThreeTenABP remains the best choice for legacy projects that cannot update AGP to 4.0+, or where APK size is critical. ThreeTenABP is also easier to set up — just one dependency and one line of initialization. According to Stack Overflow (2024), about 30% of projects with minSdk < 26 still use ThreeTenABP instead of desugaring.

Usage Examples

The first example demonstrates working with dates using ThreeTenABP. The API is identical to java.time, but imports come from org.threeten.bp. This allows you to write code that, after migration, only requires replacing imports.

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

The second example shows date formatting. DateTimeFormatter from org.threeten.bp works the same as 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)
}

The third example demonstrates working with ZonedDateTime and converting between time zones in ThreeTenABP.

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

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

Migrating from ThreeTenABP to built-in java.time

When raising minSdk to 26, you can drop ThreeTenABP and switch to built-in java.time. The migration process includes several steps and requires thorough testing.

The first step is replacing imports. Imports from org.threeten.bp are changed to java.time. In most cases, the class names match: LocalDate → java.time.LocalDate, ZonedDateTime → java.time.ZonedDateTime. The exception is DateTimeFormatter — in ThreeTenABP it is in org.threeten.bp.format, in java.time it is in java.time.format.

The second step is removing initialization. The line AndroidThreeTen.init(this) is no longer needed, as java.time is built into the Android SDK. Remove the call from Application.onCreate() and the dependency from build.gradle.

The third step is replacing the dependency with desugaring, if minSdk remains below 26. Add isCoreLibraryDesugaringEnabled = true in compileOptions and the desugar_jdk_libs dependency. This will ensure java.time works on older APIs without ThreeTenABP. According to Google I/O (2023), desugaring is the preferred approach for new projects.

groovy
// build.gradle — replace ThreeTenABP with desugaring
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    // Remove: implementation "com.jakewharton.threetenabp:threetenabp:1.4.0"
    // Add:
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

// Remove AndroidThreeTen.init(this) from Application

Frequently Asked Questions

Can ThreeTenABP be used together with desugaring?

Technically — yes, but it doesn't make sense. If desugaring is used, built-in java.time is already available. Using both libraries will lead to code duplication and increased APK size. Choose one approach for your project.

Why does ThreeTenABP require initialization in Application?

Initialization loads the IANA Time Zone Database from assets into memory. On standard JDK, tzdata is available through classpath, but Android uses AssetManager. The init() method copies data to the system directory, making it available for ZoneId.

What Android versions does ThreeTenABP support?

ThreeTenABP supports API 14+ (Android 4.0 Ice Cream Sandwich and above). Java 8 compatibility is required (sourceCompatibility and targetCompatibility in compileOptions). On API 26+, the library is not needed — use built-in java.time.

How to update time zones in ThreeTenABP?

Time zones are bundled with the library. Version 1.4.0 includes tzdata 2021a. To update, you need to update the ThreeTenABP version or manually replace tzdata in assets. The latest tzdata versions can be obtained from the IANA repository or through ThreeTen-Backport.

How to test code with ThreeTenABP?

For unit tests, use AndroidThreeTen.init(context, zoneId) with an explicit zone specification. For Robolectric tests — AndroidThreeTen.init(ApplicationProvider.getApplicationContext()). For pure JVM tests without Android — use ThreeTen-Backport directly without ThreeTenABP.

Summary

  • ThreeTenABP is an Android adapter for ThreeTen-Backport, providing the java.time API on devices with Android < 8 (API < 26).
  • Added via Gradle dependency com.jakewharton.threetenabp:threetenabp:1.4.0 and requires AndroidThreeTen.init(this) initialization in Application.onCreate().
  • Uses the org.threeten.bp package instead of java.time — the API is virtually identical, simplifying migration when moving to API 26+.
  • Main classes: LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Instant, Duration, Period, DateTimeFormatter — all available in ThreeTenABP.
  • With the advent of desugaring (AGP 4.0+), ThreeTenABP has become optional but remains relevant for legacy projects or when APK size is constrained.
  • When migrating to java.time, replace imports org.threeten.bp → java.time, remove AndroidThreeTen.init() and replace the dependency with desugar_jdk_libs.
  • For testing, use AndroidThreeTen.init(context, zoneId) with an explicit zone specification for predictable behavior.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also