Question

Get Current Local Date and Time in Kotlin for Android

kotlinandroiddatetime

Question

How can I get the current local date—day, month, and year—and the current time—hours, minutes, and seconds—in a Kotlin Android app?

I tried using:

val now = LocalDateTime.now()

but Android Studio reports that this call requires API level 26 while my app's minimum SDK version is 21. How can I obtain the current local date and time while supporting older Android versions?

Short Answer

You will learn why LocalDateTime.now() has an Android API-level warning, how local time depends on a time zone, and how to use the modern java.time API on Android API 21+ with core library desugaring. You will also see a legacy Calendar alternative for projects that cannot use desugaring.

Concept

LocalDateTime is part of Java's modern date and time API, called java.time. It represents a calendar date and clock time, such as 2025-03-08T14:30:45.

On Android, java.time is built into the platform starting at API level 26. Therefore, calling LocalDateTime.now() directly causes a warning when your app supports devices below API 26.

For Android apps with a minimum SDK below 26, the preferred solution is usually core library desugaring. Desugaring lets the Android build tools provide supported Java language and library APIs, including much of java.time, on older Android devices.

A local date and time is based on a time zone. LocalDateTime.now() uses the device's default time zone. For example, the same instant may be 09:00 in one location and 14:00 in another. If you need to record one exact point in time for storage or an API, use an Instant; convert it to local time only when displaying it.

Mental Model

Think of an Instant as a timestamp stamped on a worldwide package: it identifies one exact moment everywhere.

A LocalDateTime is the date and time printed on a wall clock: 08 March, 14:30. A wall-clock reading only makes complete sense when you know where that clock is located.

ZoneId.systemDefault() means “use the time zone currently configured on this device.” LocalDateTime.now() effectively asks the device: “What does your local wall clock say right now?”

Take Quiz

Syntax and Examples

Use LocalDateTime.now() after enabling core library desugaring for Android API 21+.

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

val now = LocalDateTime.now()

val formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
val readableDateTime = now.format(formatter)

println(readableDateTime)
// Example: 08/03/2025 14:30:45

now contains separate date and time values:

val day = now.dayOfMonth
val month = now.monthValue
val year = now.year
val hour = now.hour
val minute = now.minute
val second = now.second

To support Android versions below API 26, enable desugaring in your app module's build.gradle.kts:

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
        isCoreLibraryDesugaringEnabled = true
    }
}

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

If your project uses Groovy Gradle files (build.gradle), the equivalent setting is:

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
        coreLibraryDesugaringEnabled true
    }
}

dependencies {
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
}

Once configured, import java.time.LocalDateTime, not an Android-specific replacement.

Step by Step Execution

Consider this example:

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

fun currentLocalTimestamp(): String {
    val now = LocalDateTime.now()
    val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
    return now.format(formatter)
}

Step by step:

  1. LocalDateTime.now() reads the current date and time using the device's default time zone.
  2. The result is stored in now, for example 2025-03-08T14:30:45.123.
  3. DateTimeFormatter.ofPattern(...) creates rules for display:
    • yyyy: four-digit year
    • MM: two-digit month
    • dd: two-digit day
    • HH: hour in 24-hour time
    • mm: minutes
    • ss: seconds
  4. now.format(formatter) converts the date-time object into text such as 2025-03-08 14:30:45.
  5. The function returns the formatted text.

The formatter changes only the displayed string. The LocalDateTime value itself remains a date-time object that can be compared or manipulated.

Real World Use Cases

  • Activity logs: Show when a user created a note, submitted a form, or completed a task.
  • Booking interfaces: Display a locally understandable appointment time to the user.
  • File names: Add a timestamp such as report-2025-03-08-143045.txt.
  • Daily features: Determine today's date for a habit tracker, attendance screen, or “daily challenge.”
  • Local notifications: Build a schedule based on the user's local calendar time.
  • Data display: Convert a server timestamp into the device's local date and time before showing it in the UI.

For server communication and long-term event storage, prefer storing an Instant or an ISO-8601 timestamp with an offset. Local time alone can become ambiguous when time zones or daylight-saving rules change.

Take Quiz

Real Codebase Usage

In real Android projects, developers commonly separate time acquisition, storage, and presentation.

Get an exact current moment

import java.time.Instant

val createdAt = Instant.now()

Use this for records sent to an API or saved in a database when the event must mean the same moment everywhere.

Convert an instant for local display

import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId

val localTime = LocalDateTime.ofInstant(
    Instant.now(),
    ZoneId.systemDefault()
)

Keep formatting near the UI

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.Locale

val formatter = DateTimeFormatter.ofPattern("dd MMM yyyy, HH:mm", Locale.getDefault())
val label = LocalDateTime.now().format(formatter)

For user-facing dates, developers often use a formatter with Locale.getDefault() so month names and formatting conventions can follow the user's language and region.

Avoid creating date strings too early in your business logic. Keep date-time values as Instant, LocalDate, or LocalDateTime objects until they must be displayed or serialized.

Common Mistakes

Using LocalDateTime without Android desugaring

This is valid Kotlin, but it is not available on Android API levels below 26 unless desugaring is enabled:

val now = LocalDateTime.now()

Enable core library desugaring, or use Calendar in a legacy-only project.

Confusing mm and MM

val wrong = DateTimeFormatter.ofPattern("dd/mm/yyyy")

Lowercase mm means minutes, not months. Use uppercase MM for a numeric month:

val correct = DateTimeFormatter.ofPattern("dd/MM/yyyy")

Using hh when 24-hour time is intended

  • HH is 00–23 (24-hour clock).
  • hh is 01–12 (12-hour clock) and usually needs an a marker such as AM or PM.
val twelveHour = DateTimeFormatter.ofPattern("hh:mm:ss a")
val twentyFourHour = DateTimeFormatter.ofPattern("HH:mm:ss")

Storing a formatted local string as the source of truth

A value such as 08/03/2025 14:30:45 has no time-zone information and can be interpreted differently in different locales. Store an Instant or a properly defined date-time value; format it for display later.

Reusing SimpleDateFormat across threads

SimpleDateFormat is mutable and not thread-safe. If you must use it in legacy code, create it for the operation or carefully control access. Prefer immutable DateTimeFormatter when using java.time.

Forgetting that device time can be changed

The user or device may change the clock or time zone. Do not use local device time as a secure source for billing, authentication, or fraud-sensitive decisions; use trusted server time where needed.

Comparisons

NeedBest type or APIWhy
Current date and clock time on the deviceLocalDateTime.now()Convenient local date and time for display or local rules.
Today's date onlyLocalDate.now()No unnecessary hour, minute, or second values.
Current time onlyLocalTime.now()Useful for local time-of-day logic.
One exact global momentInstant.now()Independent of a user's location and time zone.
Date and time with a named time zoneZonedDateTimeKeeps both the clock time and zone rules.
Older Android code without desugaringCalendarAvailable on older Android versions, but more error-prone.

A legacy Calendar example:

import java.util.Calendar

val calendar = Calendar.getInstance()
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH) + 1 // Calendar months start at 0
val day = calendar.get(Calendar.DAY_OF_MONTH)
val hour = calendar.get(Calendar.HOUR_OF_DAY)
val minute = calendar.get(Calendar.MINUTE)
val second = calendar.get(Calendar.SECOND)

Calendar.MONTH is zero-based, so January is 0. This is one reason java.time is usually easier and safer to use.

Take Quiz

Cheat Sheet

// Current local date and time
val now = LocalDateTime.now()

// Individual fields
val year = now.year
val month = now.monthValue       // 1 through 12
val day = now.dayOfMonth
val hour = now.hour              // 0 through 23
val minute = now.minute
val second = now.second

// Format for display
val text = now.format(
    DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
)

// Current exact moment for storage or APIs
val instant = Instant.now()

// Convert an instant to the device's local time
val local = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())

Rules to remember:

  • Android API 26+ includes java.time natively.
  • For Android API 21–25, enable core library desugaring to use java.time.
  • MM = month; mm = minute.
  • HH = 24-hour clock; hh = 12-hour clock.
  • LocalDateTime has no stored time-zone or offset.
  • Prefer Instant for timestamps shared with servers or users in other time zones.

FAQ

Why does LocalDateTime.now() require API 26 on Android?

Android added the java.time API to the platform at API 26. For lower Android versions, enable core library desugaring or use an older API such as Calendar.

Does LocalDateTime.now() use local time?

Yes. It uses the device's current default time zone.

How do I get only the current date in Kotlin?

Use:

val today = LocalDate.now()

How do I get only the current time in Kotlin?

Use:

val time = LocalTime.now()

What format pattern should I use for day, month, year, and time?

A common 24-hour pattern is:

"dd/MM/yyyy HH:mm:ss"

Should I use Date or LocalDateTime in new Kotlin Android code?

Prefer java.time types such as Instant, LocalDate, and LocalDateTime for new code. They have clearer responsibilities and safer APIs than the older Date and Calendar classes.

How can I support Android API 21 with LocalDateTime?

Enable core library desugaring in your Android Gradle configuration and add the desugar_jdk_libs dependency.

Is LocalDateTime safe for timestamps sent to an API?

Not by itself, because it does not include a time zone or offset. Use Instant or an offset-aware ISO-8601 value for API timestamps.

Take Quiz

Mini Project

Description

Build a small Kotlin utility that creates a local timestamp suitable for an activity log. It demonstrates obtaining the device's current local time and formatting it consistently for display.

Goal

Create a function that returns a message such as Task completed at 08/03/2025 14:30:45.

Requirements

Return the current date and time in the device's local time zone.|Use a 24-hour format containing day, month, year, hour, minute, and second.|Use LocalDateTime and DateTimeFormatter.|Ensure the Android project supports API 21+ with core library desugaring enabled.

Take Quiz

Keep learning

Related questions

View more