joda-time-android: Joda-Time for Android with updatable timezone data
Joda-Time library with Android specialization
At a glance
- What is it?
- joda-time-android repackages Joda-Time as an Android library that loads its timezone database from resources instead of a JAR, so apps can ship fresh tzdb without waiting for an OS update. The README now says java.time with desugaring is the better choice, which reframes who should still adopt it.
- Who is it for?
- Adopt joda-time-android if you already have Joda-Time types throughout an app and need current tzdb on devices whose OS timezone data is stale, and accept that the README now points new code at java.time with desugaring. Do not adopt it for a greenfield project, and do not expect the README to document a migration path off the library, because it does not.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 18 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem joda-time-android solves is timezone data, not date arithmetic
Android's built-in date and time handling is the baseline here. The README frames the case bluntly: built-in timezone data is only updated when the OS is updated, and countries change their timezone rules. A device that never receives a system update keeps the tzdb it shipped with, which means offsets and daylight saving transitions can be wrong for regions that changed their rules after that build. That is the problem this library targets.
The second problem is memory. Joda-Time distributed as a plain JAR reads its timezone data through ClassLoader.getResourceAsStream(), and the README states that this greatly inflates the memory footprint on Android apps. The library's own answer is to load from Android resources instead of a JAR, which is the reason a wrapper exists at all rather than a single dependency line on upstream Joda-Time.
The audience is therefore narrow and specific: Android apps that already use Joda-Time types and need timezone correctness on devices they do not control. It is not a general date formatting convenience library, and the README no longer presents it as the default answer for new Android code.
How the library loads timezone data and initializes itself
The repository layout shows a library/ module alongside tzdata/ and utils/, with buildSrc/ and a Gradle wrapper at the root. The tzdata directory is where the packaged timezone database lives, and the library module is what ships to consumers. That split is the mechanism: timezone rules are compiled into the artifact as resources, so an app update can carry new rules without an OS update.
Initialization happens through AndroidX App Startup. The README states that because the library uses App Startup, it will not automatically initialize in non-main processes. That is a real architectural consequence, not a footnote: any component running in a separate process gets an uninitialized library unless the developer intervenes. The README gives two ways out, both shown in the tutorial below.
The README also points at DateUtils under library/src/main/java/net/danlew/android/joda/DateUtils.java, described as a port of Android's own DateUtils. That is the Android-specific surface area on top of upstream Joda-Time, and it is the part that has no equivalent if you simply depend on the upstream artifact.
Installing joda-time-android and handling multi-process initialization
The README gives one dependency line for build.gradle. The coordinates and version below are copied from it, and the version matches the most recent release listed on the repository.
dependencies {
implementation 'net.danlew:android.joda:2.14.3.1'
}After syncing, the library is on the classpath and App Startup initializes it in the main process. If your app runs components in another process, the README says initialization does not happen there automatically. For that case it gives a manifest provider entry, with the process name replaced by your own:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
android:process="[your-process-name-here]"
tools:node="merge" />The alternative the README offers is to call AppInitializer directly and initialize only this component, which avoids pulling in every other App Startup initializer for that process:
AppInitializer.getInstance(this).initializeComponent(JodaTimeInitializer::class.java)One build failure is common enough that the README documents it: a duplicate file error naming META-INF/LICENSE.txt or META-INF/NOTICE.txt. The README presents two fixes, excluding the files or merging them, both configured under packagingOptions in build.gradle. Pick one deliberately, because the two options have different consequences for what ends up in your APK.
The README's own warning is the biggest limitation
The most important line in the documentation is the warning at the top: joda-time-android is no longer a recommended solution for datetime handling on Android, and the author recommends the java.time package with desugaring if necessary. A library whose own README steers new users elsewhere is a hard signal. It does not mean the code is broken or abandoned, but it does mean you are adopting a solution the maintainer positions as a compatibility path rather than a destination.
The stated commitment is narrow. The README says joda-time-android will continue to get tzdb updates for the foreseeable future to support projects that do not want to switch datetime handling. That is a promise about timezone data, not about new features or API evolution. Read it as a maintenance boundary: timezone rules stay current, everything else is frozen.
The multi-process behavior is a second limitation that shows up at runtime rather than at build time. Because initialization runs through App Startup, a service or provider in a non-main process can reach code that expects initialized timezone data and find it absent. The README documents the workaround, but the failure mode is quiet, and quiet failures in date handling tend to surface as wrong timestamps in production rather than as crashes in testing.
Finally, this is the wrong tool if you are starting fresh. Desugaring plus java.time gives you the platform API with backported support, and it is what the README points to. Adding a Joda-Time dependency to a new codebase means adopting a type system the ecosystem is moving away from.
java.time with desugaring is the alternative the README names
The difference in approach is not cosmetic. java.time is the platform API, and desugaring lets older API levels use it by rewriting the calls at build time. There is no third-party runtime library loading its own timezone data from resources, because the timezone data comes from the platform. That removes the memory concern that motivated this library in the first place, and it removes the App Startup initialization step entirely.
The trade-off runs the other way on timezone freshness. The README's core argument for this library is that built-in timezone data only updates with the OS. If your users are on devices that receive regular updates, that argument weakens considerably. If they are not, it still holds, and desugaring does not address it.
The migration cost is the real barrier. Joda-Time types such as DateTime and the formatters built around them do not map one to one onto java.time types. An app with Joda-Time in its public API, its persistence layer, or its parsing code faces a rewrite rather than a dependency swap. That is precisely the situation the README says the library intends to keep serving.
Maintenance cost, licensing and what the repository commits to
The repository is not archived, and the most recent push was on 2026-09-13, the same date as the v2.14.3.1 release. The two releases before it were v2.14.2.1 on 2026-07-20 and v2.14.2 on 2026-04-29. The cadence visible in that list is consistent with timezone data refreshes rather than feature work, which matches what the README promises.
Upgrade cost for a consumer is low in the normal case: bump the version string in build.gradle and rebuild. The library ships no server component, no configuration file and no runtime service, so there is nothing to migrate on the operations side. The one recurring cost is the duplicate META-INF file error, which can resurface when dependencies change and the packagingOptions block no longer covers the incoming files.
The license is Apache-2.0, and the LICENSE file sits at the repository root. Apache-2.0 is a permissive license that permits commercial use and modification, and it includes a patent grant. The README's troubleshooting section deals with the practical consequence: the LICENSE.txt and NOTICE.txt files from the dependency can collide with other artifacts at packaging time, which is why those two files appear in the exclude and merge examples. If you choose the merge option, the notices end up in your APK, which is the conservative reading of the attribution requirement. This is a description of what the license and the README say, not legal advice; check the terms against your own distribution model.
Editorial conclusion
Adopt joda-time-android if you already have Joda-Time types throughout an app and need current tzdb on devices whose OS timezone data is stale, and accept that the README now points new code at java.time with desugaring. Do not adopt it for a greenfield project, and do not expect the README to document a migration path off the library, because it does not. Before committing, verify the version you depend on matches the latest release listed on the repository, and check whether your build already hits the META-INF/LICENSE.txt duplicate-file error described in the troubleshooting section.
Frequently asked questions
Is Joda-Time deprecated?
The README does not use the word deprecated, but it states that joda-time-android is no longer a recommended solution for datetime handling on Android and recommends the java.time package with desugaring instead. It also says the library will continue to receive tzdb updates to support projects that do not want to switch.
What is joda-time format?
The README does not describe a format string syntax. It points to Joda-Time's own list of benefits for background on the library and describes joda-time-android as a version of Joda-Time built with Android in mind, with a DateUtils port of Android's DateUtils as an extra utility.
How do I change the date format in Android?
The README does not cover date format patterns. It points to the DateUtils class at library/src/main/java/net/danlew/android/joda/DateUtils.java, described as a port of Android's DateUtils, as the Android-specific utility the library adds.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dlew-joda-time-android)