How to convert java.util.Date to java.sql.Date?
- Use java.time classes instead of legacy
java.sql.Datewith JDBC 4.2 or later.
- Convert to/from java.time if inter-operating with code not yet updated to java.time.
Example query with
myPreparedStatement.setObject( … , // Specify the ordinal number of which argument in SQL statement. myJavaUtilDate.toInstant() // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC). .atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`. .toLocalDate() // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object. )
Both represent a moment in UTC. but now with nanoseconds instead of milliseconds.
Both represent a date-only value without a time of day and without a time zone.
In Java 8 and later, the troublesome old date-time classes bundled with early versions of Java have been supplanted by the new java.time package. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
A SQL data type
DATE is meant to be date-only, with no time-of-day and no time zone. Java never had precisely such a class† until
java.time.LocalDate in Java 8. Let’s create such a value by getting today’s date according to a particular time zone (time zone is important in determining a date as a new day dawns earlier in Paris than in Montréal, for example).
LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) ); // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".
myPreparedStatement.setObject( 1 , localDate );
LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );
In other words, this entire Question is irrelevant under JDBC 4.2 or later.
If your JDBC driver does not perform in this manner, you need to fall back to converting to the java.sql types.
To convert, use new methods added to the old date-time classes. We can call
java.sql.Date.valueOf(…) to convert a
java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );
And going the other direction.
LocalDate localDate = sqlDate.toLocalDate();
While you should avoid using the old date-time classes, you may be forced to when working with existing code. If so, you can convert to/from java.time.
Go through the
Instant class, which represents a moment on the timeline in UTC. An
Instant is similar in idea to a
java.util.Date. But note that
Instant has a resolution up to nanoseconds while
java.util.Date has only milliseconds resolution.
Instant instant = myUtilDate.toInstant();
ZoneId zoneId = ZoneId.of ( "America/Montreal" ); ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId ); LocalDate localDate = zdt.toLocalDate();
† The java.sql.Date class pretends to be date-only without a time-of-day but actually does a time-of-day, adjusted to a midnight time. Confusing? Yes, the old date-time classes are a mess.
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
YearQuarter, and more.