Convert java.util.Date to java.time.LocalDate
Short answer
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
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();
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.
LocalDate to java.util.Date and vice versa simplest conversion?
tl;dr
Is there a simple way to convert a LocalDate (introduced with Java 8) to java.util.Date object? By 'simple', I mean simpler than this
Nope. You did it properly, and as concisely as possible.
java.util.Date.from( // Convert from modern java.time class to troublesome old legacy class. DO NOT DO THIS unless you must, to inter operate with old code not yet updated for java.time.
myLocalDate // `LocalDate` class represents a date-only, without time-of-day and without time zone nor offset-from-UTC.
.atStartOfDay( // Let java.time determine the first moment of the day on that date in that zone. Never assume the day starts at 00:00:00.
ZoneId.of( "America/Montreal" ) // Specify time zone using proper name in `continent/region` format, never 3-4 letter pseudo-zones such as “PST”, “CST”, “IST”.
) // Produce a `ZonedDateTime` object.
.toInstant() // Extract an `Instant` object, a moment always in UTC.
)
Read below for issues, and then think about it. How could it be simpler? If you ask me what time does a date start, how else could I respond but ask you “Where?”?. A new day dawns earlier in Paris FR than in Montréal CA, and still earlier in Kolkata IN, and even earlier in Auckland NZ, all different moments.
So in converting a date-only (LocalDate
) to a date-time we must apply a time zone (ZoneId
) to get a zoned value (ZonedDateTime
), and then move into UTC (Instant
) to match the definition of a java.util.Date
.
Details
Firstly, avoid the old legacy date-time classes such as java.util.Date
whenever possible. They are poorly designed, confusing, and troublesome. They were supplanted by the java.time classes for a reason, actually, for many reasons.
But if you must, you can convert to/from java.time types to the old. Look for new conversion methods added to the old classes.
java.util.Date
→ java.time.LocalDate
Keep in mind that a java.util.Date
is a misnomer as it represents a date plus a time-of-day, in UTC. In contrast, the LocalDate
class represents a date-only value without time-of-day and without time zone.
Going from java.util.Date
to java.time means converting to the equivalent class of java.time.Instant
. The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = myUtilDate.toInstant();
The LocalDate
class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
So we need to move that Instant
into a time zone. We apply ZoneId
to get a ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
From there, ask for a date-only, a LocalDate
.
LocalDate ld = zdt.toLocalDate();
java.time.LocalDate
→ java.util.Date
To move the other direction, from a java.time.LocalDate
to a java.util.Date
means we are going from a date-only to a date-time. So we must specify a time-of-day. You probably want to go for the first moment of the day. Do not assume that is 00:00:00
. Anomalies such as Daylight Saving Time (DST) means the first moment may be another time such as 01:00:00
. Let java.time determine that value by calling atStartOfDay
on the LocalDate
.
ZonedDateTime zdt = myLocalDate.atStartOfDay( z );
Now extract an Instant
.
Instant instant = zdt.toInstant();
Convert that Instant
to java.util.Date
by calling from( Instant )
.
java.util.Date d = java.util.Date.from( instant );
More info
- Oracle Tutorial
- Similar Question, Convert java.util.Date to what “java.time” type?
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
- Java 9 brought some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android (26+) bundle implementations of the java.time classes.
- For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
- If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
Convert java.time.LocalDate into java.util.Date type
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
That assumes your date chooser uses the system default timezone to transform dates into strings.
Converting from java.time.LocalDate to java.util.Date results in incorrect timestamp in Asia/Kolkata time zone
Digging through online resources, I stumbled upon JDK-8061577 which explains the behavior. It's because java.util.Calendar
supports Julian-Gregorian
calendar where as newer java.time.*
classes support ISO 8601
calendar (i.e. Proleptic-Gregorian
calendar). As calendars used are different, there can be differences that are observed while converting from one type to another based on calendar rules.
Luckily, Calendar builder allows setting calendar type to ISO 8601 which can be used as a workaround. So, following code snippet worked for us:
Date date = new Calendar.Builder().setCalendarType("iso8601")
.setDate(localDate.getYear(), localDate.getMonthValue() - 1, localDate.getDayOfMonth())
.build()
.getTime();
How to convert java.util.Date to java.time.LocalDate and preserve date/time
You can just convert it to instant, set a time zone to UTC, because java.util.Date is using UTC.
public static LocalDate convert (Date date) {
return date.toInstant()
.atZone(ZoneId.of("UTC"))
.toLocalDate();
}
java.time.LocalDate to java.util.Date
LocalDate ld = ...;
Instant instant = ld.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date res = Date.from(instant);
Check out this blog post, Converting between Date and java8 java.time.LocalDateTime, LocalDate and LocalTime by joachim.
Convert java.util.date into java.time.localdate type?
Try this:
Date inputDate = new Date();
LocalDate date = inputDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
I found this duplicated post after answer:
Convert java.util.Date to java.time.LocalDate
vaadin8 DateField: Cannot cast java.time.LocalDate to java.util.Date
The problem is how you make use of the binder
. Instead try
DateField birthdate = new DateField("birthdate");
binder.forField(birthdate).withConverter(new LocalDateToDateConverter()).bind("birthdate");
The forField
method returns an object following the builder design pattern. That means you call some (chained) methods on that object and finish it by a call to bind
.
Related Topics
Changing the Shapes of Points in Scatter Plot
How to Fetch Fetchtype.Lazy Associations with JPA and Hibernate in a Spring Controller
Parsing JSON Array into Java.Util.List with Gson
When Should I Use an Interface in Java
How to Reference Another Property in Java.Util.Properties
Jsch Algorithm Negotiation Fail
Difference Between Break and Continue Statement
Convert JSON String to Pretty Print JSON Output Using Jackson
Java: Method to Get Position of a Match in a String
Regex Date Format Validation on Java
Sorting a List of Points with Java
Ignoring Ssl Certificate in Apache Httpclient 4.3
Using Gzip Compression with Spring Boot/Mvc/Javaconfig with Restful
How to Add an Image to a Jbutton
Synchronizing on an Integer Value
Java Swing: How to Change Gui Dynamically