Kotlin

Date and Time Formatting in Kotlin with the DateTime Library

Explore the art of formatting date and time in Kotlin with the Kotlinx-datetime library. This guide introduces you to the efficient use of Unicode patterns and Kotlin DSL for formatting date and time types. Ideal for Kotlin Multiplatform projects.
Alex Zhukovich 3 min read
Date and Time Formatting in Kotlin with the DateTime Library
Table of Contents

The "kotlinx-datetime" library got an update "v0.6.0-RC" which introduces an API for locale-invariant parsing and formatting. These changes will allow for cleaning up platform-specific date and time formatting code.

In this article, we will explore options for parsing and formatting LocalDateTime, LocalDate and LocalTime types.

Several predefined formatting options exist for different date and time types. Let's check how they format a specific date and time: March 1, 2024, at 9:15 AM, represented in code as LocalDateTime(2024, 3, 1, 9, 15, 0, 0).

  • LocalDateTime
    • LocalDateTime.Formats.ISO formats it as 2024-03-01T09:15:00.
  • LocalDate
    • LocalDate.Formats.ISO formats it as 2024-03-01
    • LocalDate.Formats.ISO_BASIC formats it as 20240301
  • LocalTime
    • LocalTime.Formats.ISO formats it as 09:15:00

To use the version "0.6.0-RC" of the "kotlinx-datetime" library, you need to add a dependency to your build.gradle file or update gradle/libs.versions.toml (if you use the version catalog):

implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.6.0-RC.2"

Formatting

There are 2 ways of formatting date and time by using unicode pattern or by using Kotlin DSL. Let's explore both options.

Let's format LocalDateTime, LocalDate and LocalTime objects using different approaches.

To format different date and time types, we need to use the format(...) function.

val currentDateTime = LocalDateTime(2024, 3, 1, 9, 15, 0, 0)
val currentDate = currentDateTime.date
val currentTime = currentDateTime.time

currentDateTime.format(LocalDateTime.Format { 
    // Use Unicode Pattern or Kotlin DSL
})

currentDate.format(LocalDate.Format { 
    // Use Unicode Pattern or Kotlin DSL
})
        
currentTime.format(LocalTime.Format { 
    // Use Unicode Pattern or Kotlin DSL
})

As you can see, if we want to format LocalDate we need to use LocalDate.Format { ... } type as a parameter for the format function.

Formatting by using Unicode pattern

Let's take a look at examples of formatting date and times using the different unicode patterns:

val currentDateTime = LocalDateTime(2024, 3, 1, 9, 15, 0, 0)
val currentDate = currentDateTime.date
val currentTime = currentDateTime.time

// 2024 03 01 - 09:15
currentDateTime.format(LocalDateTime.Format { byUnicodePattern("yyyy MM dd - HH:mm") })

// 2024/03/01
currentDate.format(LocalDate.Format { byUnicodePattern("yyyy/MM/dd") })

// 09:15 
currentTime.format(LocalTime.Format { byUnicodePattern("HH:mm") })

Formatting by using Kotlin DSL

Let's examine formatting dates and times using Kotlin DSL:

val currentDateTime = LocalDateTime(2024, 3, 1, 9, 15, 0, 0)
val currentDate = currentDateTime.date
val currentTime = currentDateTime.time

// Mar 01 2024 - 09:15
currentDateTime.format(
    LocalDateTime.Format {
        date(
            LocalDate.Format {
                monthName(MonthNames.ENGLISH_ABBREVIATED)
                char(' ')
                dayOfMonth()
                chars(" ")
                year()
            }
        )
        chars(" - ")
        time(
            LocalTime.Format {
                hour(); char(':'); minute()
            }
        )
    }
)

// Mar 01, 2024
currentDate.format(LocalDate.Format {
    monthName(MonthNames.ENGLISH_ABBREVIATED)
    char(' ')
    dayOfMonth()
    chars(", ")
    year()
})

// 09:15
currentTime.format(LocalTime.Format {
    hour()
    char(':')
    minute()
})
The hour() function returns the hour value between 0 and 23 hours, but if you want the hour of the day in the 12-hour clock, you need to use the amPmHour() function.

When you use the Kotlin DSL approach, you can pass the padding parameters to functions like: year(), monthNumber(), dayOfMonth(), hour(), minute() and it will change the style of padding to use when formatting a value. To understand it better, let's take a look at an example of formatting the "09:08 (AM)" time.

val time = LocalTime(hour = 9, minute = 8)

// "9:8"
time.format(LocalTime.Format { 
    hour(padding = Padding.NONE)
    char(':')
    minute(padding = Padding.NONE) 
})

// "09:08"
time.format(LocalTime.Format { 
    hour(padding = Padding.ZERO)
    char(':')
    minute(padding = Padding.ZERO) 
})

// " 9: 8"
time.format(LocalTime.Format { 
    hour(padding = Padding.SPACE)
    char(':')
    minute(padding = Padding.SPACE) 
})

Parsing

To parse a formatted date and time into LocalDateTime, LocalDate, or LocalTime, we use the parse method on the respective type.

val formattedDateTime = "2024 03 01 - 09:15"
LocalDateTime.parse(
    input = formattedDateTime,
    format = LocalDateTime.Format { byUnicodePattern("yyyy MM dd - HH:mm") }
)

val formattedDate = "2024/03/01"
LocalDate.parse(
    input = formattedDate,
    format = LocalDate.Format { byUnicodePattern("yyyy/MM/dd") }
)

val formattedTime = "09:15"
LocalTime.parse(
    input = formattedTime,
    format = LocalTime.Formats.ISO
)

Summary

The "kotlinx-datetime:v0.6.0-RC" release provides multiple options for working with date and time independently of the platforms.

Date and time can be formatted using one of the available formatting options:

  • unicode pattern
  • Kotlin DSL

Date and time types can be parsed using the parse function on an appropriate class, like LocalTime.parse and providing the format of the value.

Remember to clean up the platform-specific code for date formatting if you decided to use the new pre-release version of the "kotlinx-datetime" library.


Mobile development with Alex

A blog about Android development & testing, Best Practices, Tips and Tricks

Share
More from Mobile development with Alex
Guide: Ranges in Kotlin
Kotlin

Guide: Ranges in Kotlin

Let's explore Ranges in Kotlin and understand how it can simplify development. In the end, we create a custom range for the delivery time of a restaurant base on open and close time.
Alex Zhukovich 6 min read

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to Mobile development with Alex.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.