Convert between LocalDate and sql.Date
96,021
The Java 8 version (and later) of java.sql.Date
has built in support for LocalDate
, including toLocalDate
and valueOf(LocalDate)
.
To convert from LocalDate
to java.sql.Date
you can use
java.sql.Date.valueOf( localDate );
And to convert from java.sql.Date
to LocalDate
:
sqlDate.toLocalDate();
Time zones:
The LocalDate
type stores no time zone information, while java.sql.Date
does. Therefore, when using the above conversions, the results depend on the system's default timezone (as pointed out in the comments).
If you don't want to rely on the default timezone, you can use the following conversion:
Date now = new Date();
LocalDate current = now.toInstant()
.atZone(ZoneId.systemDefault()) // Specify the correct timezone
.toLocalDate();
Author by
maja
Updated on July 05, 2022Comments
-
maja almost 2 years
What's the correct way to convert between
java.sql.Date
andLocalDate
(in both directions) in Java 8 (or higher)? -
marc82ch about 8 yearsNote that this uses the system default time zone to interpret the date, which may or may not be what you want. Often it's preferrable to specify the time zone explicitly!
-
beldaz almost 8 years@marc82ch A
LocalDate
explicitly doesn't have a time zone. Can you add some details of how you would specify one and how that would affect things? -
marc82ch almost 8 years@beldaz I may be wrong, I don't know the internals really, but I think a java.sql.Date is represented by a long timestamp since the epoch (UTC). So, when reading from the DB DATE field, it needs to be interpreted (by the driver) in order to represent it as a long. Remember that java.sql.Date inherits from java.util.Date. So it's basically an Instant in Java 8 terms and converting it to a LocalDate needs a time zone. But I reckon that as long as the JDBC driver and your code use the same default time zone, it doesn't matter.
-
Josiah Yoder almost 7 years@marc82ch You are correct. The default time zone affects the conversion, as proved by this question. you can use the yyyy-mm-dd format while converting:
java.time.LocalDate.parse(sqlDate.toString())
@maja, Can you update your answer accordingly? -
TheCodeKiller about 6 yearsAlternative is incorrect as java.sql.Date.toInstant() throws a UnsupportedOperationException (in Java 8)
-
Ednilson Campos about 6 yearsUnsupportedOperationException is throws in java.util.Date, not in java.sql.Date, for avoid this exception use a if (sqlDate instanceof java.sql.Date) before the sqlDate.toLocalDate(), if the date is java.util.Date use sqlDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-
Shubham Pandey over 5 yearsI also got UnsupportedOperationException. For me this worked -> Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()
-
codeling over 5 yearssomehow there is an unwanted timezone conversion going on for me in those java.sql.Date methods - I put in a LocalDate for today, and in the database end up with a date value for yesterday
-
JayC667 almost 4 years@codeling When writing to the DB, use the method
statement.setDate(2, Date.valueOf(record.date), cal);
with 'cal' being an instance of Calendar (Calendar.getInstance()). This way the driver will have the proper context. If you do not use the default system timezone, get a calendar for that zone and pass it in. -
Artanis about 3 yearsthrows exception when used w/ java.sql.date in java 8