Short answer

Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

Java 9 answer

In Java SE 9, a new method has been added that slightly simplifies this task:

Date input = new Date();
LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());

This new alternative is more direct, creating less garbage, and thus should perform better.

Explanation

Despite its name, java.util.Date represents an instant on the time-line, not a "date". The actual data stored within the object is a long count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).

The equivalent class to java.util.Date in JSR-310 is Instant, thus there is a convenient method toInstant() to provide the conversion:

Date input = new Date();
Instant instant = input.toInstant();

A java.util.Date instance has no concept of time-zone. This might seem strange if you call toString() on a java.util.Date, because the toString is relative to a time-zone. However that method actually uses Java's default time-zone on the fly to provide the string. The time-zone is not part of the actual state of java.util.Date.

An Instant also does not contain any information about the time-zone. Thus, to convert from an Instant to a local date it is necessary to specify a time-zone. This might be the default zone - ZoneId.systemDefault() - or it might be a time-zone that your application controls, such as a time-zone from user preferences. Use the atZone() method to apply the time-zone:

Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());

A ZonedDateTime contains state consisting of the local date and time, time-zone and the offset from GMT/UTC. As such the date - LocalDate - can be easily extracted using toLocalDate():

Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDate date = zdt.toLocalDate();
Answer from JodaStephen on Stack Overflow
🌐
Kotlin
kotlinlang.org › api › kotlinx-datetime › kotlinx-datetime › kotlinx.datetime › to-local-date-time.html
toLocalDateTime | kotlinx-datetime – Kotlin Programming Language
Returns a civil datetime value that this instant has in the specified timeZone. Note that while this conversion is unambiguous, the inverse (LocalDateTime.toInstant) is not necessarily so.
Discussions

datetime - Convert java.util.Date to java.time.LocalDate - Stack Overflow
DateTimeUtils wasn't available when I was using the backport, but you are correct that it is available to anyone using ThreeTen Backport 1.0 or later. Thanks for pointing it out. 2016-03-18T16:15:28.497Z+00:00 ... @ChristianCiach You are correct. I spelled out what you are saying in this answer. 2020-07-24T06:56:19.75Z+00:00 ... And it simplest realization: LocalDate... More on stackoverflow.com
🌐 stackoverflow.com
android - How to convert LocalDate to LocalDateTime in Kotlin - Stack Overflow
Hi how can I convert LocalDate to LocalDateTime using org.threeten.bp I have a date 2022-July-27, which is LocalDate, how can I convert to LocalDateTime please Thanks R More on stackoverflow.com
🌐 stackoverflow.com
android - How to get current local date and time in Kotlin - Stack Overflow
How to get current Date (day month and year) and time (hour, minutes and seconds) all in local time in Kotlin? I tried through LocalDateTime.now() but it is giving me an error saying Call requires API Level 26 (curr min is 21). More on stackoverflow.com
🌐 stackoverflow.com
kotlin - How to get current date with reset time 00:00 with Kotlinx.LocalDateTime? - Stack Overflow
You can pass the the desired LocalDate to it along with LocalTime.MIN, which will result in a LocalDateTime at the specific date with a local time of 00:00:00. Have a look at the sources of the kotlinx-datetime project More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › Kotlin › kotlinx-datetime
GitHub - Kotlin/kotlinx-datetime: KotlinX multiplatform date/time library · GitHub
LocalDate to represent the components of date only; YearMonth to represent only the year and month components; LocalTime to represent the components of time only; TimeZone and FixedOffsetTimeZone provide time zone information to convert between kotlin.time.Instant and LocalDateTime;
Starred by 2.8K users
Forked by 131 users
Languages   Kotlin
Top answer
1 of 14
1002

Short answer

Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

Java 9 answer

In Java SE 9, a new method has been added that slightly simplifies this task:

Date input = new Date();
LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());

This new alternative is more direct, creating less garbage, and thus should perform better.

Explanation

Despite its name, java.util.Date represents an instant on the time-line, not a "date". The actual data stored within the object is a long count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).

The equivalent class to java.util.Date in JSR-310 is Instant, thus there is a convenient method toInstant() to provide the conversion:

Date input = new Date();
Instant instant = input.toInstant();

A java.util.Date instance has no concept of time-zone. This might seem strange if you call toString() on a java.util.Date, because the toString is relative to a time-zone. However that method actually uses Java's default time-zone on the fly to provide the string. The time-zone is not part of the actual state of java.util.Date.

An Instant also does not contain any information about the time-zone. Thus, to convert from an Instant to a local date it is necessary to specify a time-zone. This might be the default zone - ZoneId.systemDefault() - or it might be a time-zone that your application controls, such as a time-zone from user preferences. Use the atZone() method to apply the time-zone:

Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());

A ZonedDateTime contains state consisting of the local date and time, time-zone and the offset from GMT/UTC. As such the date - LocalDate - can be easily extracted using toLocalDate():

Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDate date = zdt.toLocalDate();
2 of 14
194

Better way is:

Date date = ...;
Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()

Advantages of this version:

  • works regardless the input is an instance of java.util.Date or it's a subclass of java.sql.Date (unlike @JodaStephen's way). This is common with JDBC-originated data. java.sql.Date.toInstant() always throws an exception.

  • it's the same for JDK8 and JDK7 with JSR-310 backport

I personally use an utility class (but it is not backport-compatible):

/**
 * Utilities for conversion between the old and new JDK date types 
 * (between {@code java.util.Date} and {@code java.time.*}).
 * 
 * <p>
 * All methods are null-safe.
 */
public class DateConvertUtils {

    /**
     * Calls {@link #asLocalDate(Date, ZoneId)} with the system default time zone.
     */
    public static LocalDate asLocalDate(java.util.Date date) {
        return asLocalDate(date, ZoneId.systemDefault());
    }

    /**
     * Creates {@link LocalDate} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static LocalDate asLocalDate(java.util.Date date, ZoneId zone) {
        if (date == null)
            return null;

        if (date instanceof java.sql.Date)
            return ((java.sql.Date) date).toLocalDate();
        else
            return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDate();
    }

    /**
     * Calls {@link #asLocalDateTime(Date, ZoneId)} with the system default time zone.
     */
    public static LocalDateTime asLocalDateTime(java.util.Date date) {
        return asLocalDateTime(date, ZoneId.systemDefault());
    }

    /**
     * Creates {@link LocalDateTime} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static LocalDateTime asLocalDateTime(java.util.Date date, ZoneId zone) {
        if (date == null)
            return null;

        if (date instanceof java.sql.Timestamp)
            return ((java.sql.Timestamp) date).toLocalDateTime();
        else
            return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDateTime();
    }

    /**
     * Calls {@link #asUtilDate(Object, ZoneId)} with the system default time zone.
     */
    public static java.util.Date asUtilDate(Object date) {
        return asUtilDate(date, ZoneId.systemDefault());
    }

    /**
     * Creates a {@link java.util.Date} from various date objects. Is null-safe. Currently supports:<ul>
     * <li>{@link java.util.Date}
     * <li>{@link java.sql.Date}
     * <li>{@link java.sql.Timestamp}
     * <li>{@link java.time.LocalDate}
     * <li>{@link java.time.LocalDateTime}
     * <li>{@link java.time.ZonedDateTime}
     * <li>{@link java.time.Instant}
     * </ul>
     * 
     * @param zone Time zone, used only if the input object is LocalDate or LocalDateTime.
     * 
     * @return {@link java.util.Date} (exactly this class, not a subclass, such as java.sql.Date)
     */
    public static java.util.Date asUtilDate(Object date, ZoneId zone) {
        if (date == null)
            return null;

        if (date instanceof java.sql.Date || date instanceof java.sql.Timestamp)
            return new java.util.Date(((java.util.Date) date).getTime());
        if (date instanceof java.util.Date)
            return (java.util.Date) date;
        if (date instanceof LocalDate)
            return java.util.Date.from(((LocalDate) date).atStartOfDay(zone).toInstant());
        if (date instanceof LocalDateTime)
            return java.util.Date.from(((LocalDateTime) date).atZone(zone).toInstant());
        if (date instanceof ZonedDateTime)
            return java.util.Date.from(((ZonedDateTime) date).toInstant());
        if (date instanceof Instant)
            return java.util.Date.from((Instant) date);

        throw new UnsupportedOperationException("Don't know hot to convert " + date.getClass().getName() + " to java.util.Date");
    }

    /**
     * Creates an {@link Instant} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static Instant asInstant(Date date) {
        if (date == null)
            return null;
        else
            return Instant.ofEpochMilli(date.getTime());
    }

    /**
     * Calls {@link #asZonedDateTime(Date, ZoneId)} with the system default time zone.
     */
    public static ZonedDateTime asZonedDateTime(Date date) {
        return asZonedDateTime(date, ZoneId.systemDefault());
    }

    /**
     * Creates {@link ZonedDateTime} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static ZonedDateTime asZonedDateTime(Date date, ZoneId zone) {
        if (date == null)
            return null;
        else
            return asInstant(date).atZone(zone);
    }

}

The asLocalDate() method here is null-safe, uses toLocalDate(), if input is java.sql.Date (it may be overriden by the JDBC driver to avoid timezone problems or unnecessary calculations), otherwise uses the abovementioned method.

🌐
Android Developers
developer.android.com › api reference › localdate
LocalDate | API reference | Android Developers
Skip to main content · English · Deutsch · Español – América Latina · Français · Indonesia · Polski · Português – Brasil · Tiếng Việt · 中文 – 简体
🌐
Kotlin
kotlinlang.org › api › kotlinx-datetime › kotlinx-datetime › kotlinx.datetime › -local-date-time › -local-date-time.html
LocalDateTime | kotlinx-datetime – Kotlin Programming Language
Constructs a LocalDateTime instance from the given date and time components. ... year the range is platform-dependent, but at least is enough to represent dates of all instants between Instant.DISTANT_PAST and Instant.DISTANT_FUTURE ... import ...
🌐
Kotlin
kotlinlang.org › api › kotlinx-datetime › kotlinx-datetime › kotlinx.datetime.format › -date-time-components › to-local-date.html
toLocalDate | kotlinx-datetime – Kotlin Programming Language
import kotlinx.datetime.* import kotlinx.datetime.format.* import kotlin.test.* import kotlin.time.Instant fun main() { //sampleStart // Obtaining a LocalDate from the parsed data val rfc1123Input = "Sun, 06 Nov 1994 08:49:37 +0300" val parsed = DateTimeComponents.Formats.RFC_1123.parse(rfc1123Input) val localDate = parsed.toLocalDate() check(localDate == LocalDate(1994, 11, 6)) //sampleEnd }
🌐
Baeldung
baeldung.com › home › kotlin › kotlin dates › working with dates in kotlin
Working with Dates in Kotlin | Baeldung on Kotlin
June 20, 2022 - var date = LocalDate.parse("2018-12-31") assertThat(date.year).isEqualTo(2018) assertThat(date.month).isEqualTo(Month.DECEMBER) assertThat(date.dayOfMonth).isEqualTo(31) We can also extract other information like era, dayOfTheWeek or dayOfTheMonth: assertThat(date.era.toString()).isEqualTo("CE") assertThat(date.dayOfWeek).isEqualTo(DayOfWeek.MONDAY) assertThat(date.dayOfYear).isEqualTo(365) Finally, let’s look into working with Periods in Kotlin.
Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 73141884 › how-to-convert-localdate-to-localdatetime-in-kotlin
android - How to convert LocalDate to LocalDateTime in Kotlin - Stack Overflow
FYI, Android supports Java 8 java.time fully through desugaring now, so it's unnecessary to use a backport library. Anyway, just call atStartOfDay() or atTime() on your LocalDate.
🌐
Bugfender
bugfender.com › blog › kotlin-dates
Mastering Date and Time Handling in Kotlin for Android Developers | Bugfender
October 8, 2024 - An instant represents a specific moment on the UTC-SLS timeline. Usage Scenario: The recording generated when a user submits a form: ... LocalDateTime is a combination of date and time, minus timezone specifics.
🌐
Luasoftware
code.luasoftware.com › tutorials › kotlin › convert-localdate-to-localdatetime
Convert LocalDate to LocalDateTime (Kotlin)
August 7, 2019 - Related articlesUnderstanding Date/Timestamp in Firestore for Multiple Timezones SupportAndroid Time Picker Dialog With Java Time (Kotlin)Android Date Picker Dialog With Java Time (Kotlin)Parse Date String to LocaldateCovert ZoneId to ZoneOffsetJava Time Calculate Days Between 2 LocalDateDateTimeParseException: Unable to obtain LocalDateTime from TemporalAccessorParse String to Java Time LocalDateTimeAndroid Format Date RangeTimestamp Epoch to LocalDateTime / Java8 Date TimeJava 8 Date Time: Extract Time From Date and Remove Seconds (Kotlin)Java Time/LocalDateTime (Java 8): Add Days or Add Min
🌐
GitHub
github.com › Kotlin › kotlinx-datetime › discussions › 253
Localized date-time formats · Kotlin/kotlinx-datetime · Discussion #253
... magine that kotlinx-datetime has with things like ES_ES_FORMAT = "d 'de' MMMM 'de' yyyy" built in for each locale. You'd write LocalDate.Format(Locale("es_es")) { year(); monthName(); dayOfMonth() }, and it would output 12 de marzo de 1994.
Author   Kotlin
🌐
Medium
medium.com › @atharvapajgade › working-with-date-objects-in-kotlin-e6af6cb9688c
Working with date objects in Kotlin | by Atharva pajgade | Medium
November 24, 2025 - fun Long.toLocalDate(): LocalDate { //works on API levels >= 26 LocalDateTime.ofInstant( Instant.ofEpochMilli(this) , ZoneId.systemDefault() ).toLocalDate() } ... fun formatDate(){ val date = Date(System.currentTimeMillis()) val formatter = SimpleDateFormat("yyyy dd MMM hh") println(formatter.format(date)) } //output 2025 25 Nov 12
🌐
Android Developers
developer.android.com › api reference › localdatetime
LocalDateTime | API reference | Android Developers
Skip to main content · English · Deutsch · Español – América Latina · Français · Indonesia · Polski · Português – Brasil · Tiếng Việt · 中文 – 简体
🌐
Medium
raed-o-ghazal.medium.com › kotlinx-localdatetime-manipulation-for-kmm-eacfede93aba
Kotlinx.datetime manipulation KMP | by Raed Ghazal | Medium
September 10, 2024 - For addition and subtraction, unfortunately, we can’t do it directly from LocalDateTime instance, we have to convert it to Instant, do the calculation, and then convert it back to LocalDateTime, so here are some more extension functions · import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone import kotlinx.datetime.minus import kotlinx.datetime.plus import kotlinx.datetime.toInstant import kotlinx.datetime.toLocalDateTime
🌐
Kotlin
kotlinlang.org › api › kotlinx-datetime › kotlinx-datetime › kotlinx.datetime › -local-date › -formats › -i-s-o.html
ISO | kotlinx-datetime – Kotlin Programming Language
See ISO-8601-1:2019, 5.2.2.1b), using the "expanded calendar year" extension from 5.2.2.3a), generalized to any number of digits in the year for years that fit in an Int. import kotlinx.datetime.* import kotlinx.datetime.format.* import kotlin.random.* import kotlin.test.* fun main() { //sampleStart // Using the extended ISO format for parsing and formatting LocalDate values val date = LocalDate.Formats.ISO.parse("2024-04-16") check(date == LocalDate(2024, Month.APRIL, 16)) val formatted = LocalDate.Formats.ISO.format(date) check(formatted == "2024-04-16") //sampleEnd } actual val ISO: DateTimeFormat<LocalDate>(source)
🌐
Kotlin
kotlinlang.org › api › latest › jvm › stdlib › kotlin.js › -date
Date - Kotlin Programming Language
July 12, 2023 - fun toLocaleTimeString( locales: String, options: LocaleOptions = definedExternally ): String
🌐
Baeldung
baeldung.com › home › kotlin › kotlin dates › guide to the kotlinx date/time library
Guide to the KotlinX Date/Time Library | Baeldung on Kotlin
April 15, 2025 - In the above example, we created an instance of LocalDateTime with the system default TimeZone, which is UTC. Even though we can get a human-readable String from an Instant, combining it with a TimeZone is the correct way to get a representation for the client side. TimeZone is frequently an issue, especially in distributed applications. We should store time representations without a specific time zone. So, kotlinx-datetime makes it easy to combine Instant and TimeZone to get the LocalDateTime.