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
.
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.
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();
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 );
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?
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.