Modern date and time handling in all Android versions (without sugar)
Working with time in Android has always been tricky. People have been using either third party libraries (e.g. Joda-Time, ThreeTenBp) or had to work with the built-in time classes (such as Calendar). The built-in classes, although available in all Android versions, had a not-so-great API, were mutable (so not thread-safe), and timezone handling was a pain (ref).
In the latest Android Gradle plugin release (v.4.0.0+), "Java 8+ API desugaring support" was introduced. In plain language, we can use some Java 8 APIs and the plugin will translate those APIs to Android-compatible Java behind the scenes that can be used in all Android versions without requiring a minimum API level!
In general, Kotlin provides its Collections and Stream API replacements which are superior to Java's in my opinion. So from the list of Java 8 APIs, I think that only the excellent java.time API is interesting for a Kotlin developer. Finally, a nice date/time API that can be used in Android!
Note that this "desugaring" process might cost a few extra KB in your APK/AAB. But if that's not a deal-breaker for your case, you should consider using the newer APIs.
Set up
You would need to modify your build.gradle
files. More details (and up-to-date version codes) in the official doc.
android {
[...]
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled true
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
[...]
}
dependencies {
[...]
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
[...]
}
Meet the classes
The time API is quite comprehensive and the complete exploration of the API is outside of the scope of this post. But, I want to introduce what I believe the main classes you probably going to need most of the time.
Instant
Instant is a point in time. Can be considered equivalent to a timestamp, if you are familiar with that term.
LocalTime, LocalDate, LocalDateTime
Each class represents the time, date, date+time respectively, without a timezone. Most people when thinking about date/time think in these terms anyway.
ZoneOffset, ZoneId
These are used to work with timezones. You would need one of those to convert a Local*
to an Instant
.
ZonedDateTime
You probably guessed it. This is what you get when combine a LocalDateTime
with a ZoneId
. This can be converted to an Instant
.
Playing with date and time
These APIs provide intuitive and consistent ways to manipulate date and time. Remember that all objects are immutable, so a new object is created every time that a manipulation takes place (which is a good thing). Some useful examples follow.
Formatting
Just note that the formatters you are used to in Android, such as SimpleDateFormat
, cannot be used with Java Time API. The API comes with its own formatters, such as DateTimeFormatter
.
DateTimeFormatter.ISO_DATE.format(instant)
Enjoy a modern date/time API in your Android development life :)