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();
Share:
96,021
maja
Author by

maja

Updated on July 05, 2022

Comments

  • maja
    maja almost 2 years

    What's the correct way to convert between java.sql.Date and LocalDate (in both directions) in Java 8 (or higher)?

  • marc82ch
    marc82ch about 8 years
    Note 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
    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
    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
    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
    TheCodeKiller about 6 years
    Alternative is incorrect as java.sql.Date.toInstant() throws a UnsupportedOperationException (in Java 8)
  • Ednilson Campos
    Ednilson Campos about 6 years
    UnsupportedOperationException 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()).toLocalDa‌​te();
  • Shubham Pandey
    Shubham Pandey over 5 years
    I also got UnsupportedOperationException. For me this worked -> Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDef‌​ault()).toLocalDate(‌​)
  • codeling
    codeling over 5 years
    somehow 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
    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
    Artanis about 3 years
    throws exception when used w/ java.sql.date in java 8