javajodatime

What is the correct way to go from LocalDate to java.sql.Date


I have a LocalDate that I'm trying to convert to a java.sql.Date to store it in a Date field in the DB. My problem is that when I convert it to a java.sql.Date it is one day behind due to the machine I'm running on being in EST. I setup Joda.DateTime to be in UTC, and creating the java.sql.Date via using the millis constructor. I'm including the output of the debug watches so you can see what the different values are:

item.getDate().toDateTimeAtStartOfDay() = {org.joda.time.DateTime@6079}"2013-09-25T00:00:00.000Z"
item.getDate().toDateTimeAtStartOfDay().getMillis() = 1380067200000
new java.sql.Date(item.getDate().toDateTimeAtStartOfDay().getMillis()) = {java.sql.Date@6082}"2013-09-24"
item.getDate().getLocalMillis() = 1380067200000
new java.sql.Date(item.getDate().getLocalMillis()) = {java.sql.Date@6083}"2013-09-24"
new java.util.Date(item.getDate().getLocalMillis()) = {java.util.Date@6103}"Tue Sep 24 20:00:00 EDT 2013"

From the java.util.Date creation I'm assuming it is because my machine I'm testing on is in EST, and the LocalDate is in UTC, but I'm not sure what the correct way to fix this is. I realize I could get the local timezone and add that to the millis, but that seems like a hacky fix. Is there a proper way to do this that I'm just missing?


Update with the millis for the java.util.Date

new java.util.Date(item.getDate().getLocalMillis()).getTime() = 1380153600000
item.getDate().toDateTimeAtStartOfDay().getMillis() = 1380153600000
item.getDate() = {org.joda.time.LocalDate@5812}"2013-09-26"
new java.sql.Date(item.getDate().getLocalMillis()).getTime() = 1380153600000
new java.util.Date(item.getDate().getLocalMillis()) = {java.util.Date@5842}"Wed Sep 25 20:00:00 EDT 2013"
new java.util.Date(item.getDate().getLocalMillis()).getTime() = 1380153600000

Solution

  • The proper conversions are:

        public static final DateTimeZone jodaTzUTC = DateTimeZone.forID("UTC");
    
        // from  java.sql.Date  to LocalDate:
        public static LocalDate dateToLocalDate(java.sql.Date d) {
            if(d==null) return null;
            return new LocalDate(d.getTime(), jodaTzUTC);
        }
    
        // from  LocalDate to java.sql.Date:
        public static java.sql.Date localdateToDate(LocalDate ld) {
            if(ld==null) return null;
            return new java.sql.Date(
                 ld.toDateTimeAtStartOfDay(jodaTzUTC).getMillis());
        }
    

    I use this in my DAO helper logic. In JDBC you should do

     public static final Calendar calendarUTC = Calendar.getInstance(
           TimeZone.getTimeZone("UTC"));
    
     d = rs.getDate(i, calendarUTC);
    

    And the same for the setter.