Date
EN

Dealing with Date objects in Android

A deep dive into the evolution of Java's date and time APIs, from java.util.Date to modern alternatives like java.time, Joda-Time, ThreeTen, and kotlinx-datetime for Android development.

3 min read
Contents

History of Date in Java

Working with dates in software development presents complex challenges. Java has evolved through multiple iterations of date and time APIs, each with distinct strengths and weaknesses. This article explores the evolution of these APIs and their application in Android development.

java.util

πŸ“œ History

Java developers received java.util.Date in JDK 1.0 (1996), marking an initial effort toward platform-independent date handling. However, the design had fundamental flaws:

  • No timezone support
  • Mutable state: Setters allowed users to modify internal values, complicating date reasoning
  • Not thread-safe, problematic for concurrent environments

Java 1.1 introduced java.util.Calendar to address these issues, though it proved complex and challenging to implement.

Example Code Issue

val date = Date().apply {
    year = 2023 // Mutable
    month = 4   // Mutable
    day = 27    // Error - not mutable
}
// Result: Tue May 29 16:56:04 UTC 3923 (1900 + 2023)

🌍 In the Android World

Android relied on java.util.Date and java.util.Calendar since API Level 1, as Java 1.8 wasn’t initially available.

DatePickerDialog Example:

val calendar = Calendar.getInstance()
val currentYear = calendar.get(Calendar.YEAR)
val currentMonth = calendar.get(Calendar.MONTH)
val currentDay = calendar.get(Calendar.DAY_OF_MONTH)

val datePickerDialog = DatePickerDialog(this, { _, year, month, day ->
    val selectedDate = Calendar.getInstance()
    selectedDate.set(year, month, day)
    val selectedDateObj = selectedDate.time
    handleSelectedDate(selectedDateObj)
}, currentYear, currentMonth, currentDay)

datePickerDialog.show()

Joda-Time

πŸ“œ History

Released in 2002, Joda-Time emerged as an open-source alternative emphasizing domain-driven development principles. Key advantages included:

  • Immutability: Once created, objects couldn’t be modified
  • Rich helper methods for parsing, formatting, interval calculation, and timezone adjustment
  • New DateTime class with comprehensive date/time features

🌍 In the Android World

Developer Dan Lew famously noted: β€œI’ve recently gotten fed up with how nuts the built-in calendar library is for Java/Android.” A critical issue involved timezone database maintenance within JAR files.

Developers had to manually update TZ.data files within Joda’s JAR, requiring users to update their apps for timezone rule changes.

ThreeTen

πŸ“œ History

JSR-310 launched in 2007, influenced by Joda-Time to address java.util.Date shortcomings. Due to Java 8 release delays, the ThreeTenBP backport was created, providing JSR-310 functionality for Java 6 and 7.

🌍 In the Android World

ThreeTenABP upgraded Joda-Android, incorporating JSR-310 standards with current timezone rules. An update.sh script automates timezone database updates:

# Download latest ThreeTen release
wget --trust-server-names "https://search.maven.org/..."

# Replace embedded TZDB
rm ../threetenabp/src/main/assets/org/threeten/bp/TZDB.dat
mv org/threeten/bp/TZDB.dat ../threetenabp/src/main/assets/org/threeten/bp/

Zone Rules Initialization:

public static void init(Context context, String assetPath) {
    if (!initialized.getAndSet(true)) {
      ZoneRulesInitializer.setInitializer(
        new AssetsZoneRulesInitializer(context, assetPath)
      );
    }
}

java.time

πŸ“œ History

Introduced in Java 8, java.time represents the latest evolution, offering an intuitive API, immutability, superior timezone handling, and ISO calendar support.

🌍 In the Android World

Android Gradle plugin 4.0.0+ extends Java 8 language API support without requiring elevated minimum API levels. A java.time subset is supported through desugaring.

Configuration:

android {
    defaultConfig {
        multiDexEnabled = true  // For minSdkVersion 20 or lower
    }
    
    compileOptions {
        isCoreLibraryDesugaringEnabled = true  // AGP 4.1+
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

dependencies {
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2")
}

Refer to official documentation for comprehensive Java 8 features and API guidance.

Timezone Rules: Details on timezone rule handling are deferred to the series’ final article.

kotlinx-datetime

πŸ“œ History

kotlinx-datetime provides a Kotlin-specific, multiplatform date-handling library supporting JVM, Android, and native platforms. On Kotlin/JVM, it builds upon java.time with Kotlin-specific enhancements.

🌍 In the Android World

Current Status:

  • Alpha stage with ongoing development
  • Full Kotlin Multiplatform support
  • @Serializable annotation support
  • Simplified API via Kotlin extension functions

ISO-8601 Format Examples:

"2010-06-01T22:19:44.475Z".toInstant()
"2010-06-01T22:19:44".toLocalDateTime()
"2010-06-01".toLocalDate()
"12:01:03".toLocalTime()
"12:0:03.999".toLocalTime()

Conclusion

The evolution from java.util.Date to modern alternatives demonstrates how the Java ecosystem continues to improve date and time handling. Today’s developers have robust options from java.time for general use to kotlinx-datetime for Kotlin Multiplatform projects. Understanding this history helps in choosing the right tool for your Android development needs.