Каков правильный путь от LocalDate до java.sql.Date

У меня есть LocalDate, который я пытаюсь преобразовать в java.sql.Date, чтобы сохранить его в поле Date в БД. Моя проблема заключается в том, что когда я конвертирую его в java.sql.Date, он на один день отстает из-за того, что машина работает на EST. Я устанавливаю Joda.DateTime в UTC и создаю java.sql.Date с помощью конструктора millis. Я включаю вывод отладочных часов, чтобы вы могли видеть, что представляют собой разные значения:

item.getDate().toDateTimeAtStartOfDay() = {[email protected]}"2013-09-25T00:00:00.000Z"
item.getDate().toDateTimeAtStartOfDay().getMillis() = 1380067200000
new java.sql.Date(item.getDate().toDateTimeAtStartOfDay().getMillis()) = {[email protected]}"2013-09-24"
item.getDate().getLocalMillis() = 1380067200000
new java.sql.Date(item.getDate().getLocalMillis()) = {[email protected]}"2013-09-24"
new java.util.Date(item.getDate().getLocalMillis()) = {[email protected]}"Tue Sep 24 20:00:00 EDT 2013"

Из создания java.util.Date я предполагаю, что это потому, что моя машина, на которой я тестирую, находится в EST, а LocalDate - в UTC, но я не уверен, какой правильный способ исправить это. Я понимаю, что могу получить локальный часовой пояс и добавить это к миллисам, но это похоже на хакерское исправление. Есть ли способ сделать это, что я просто отсутствую?


Обновление с помощью миллиса для java.util.Date

new java.util.Date(item.getDate().getLocalMillis()).getTime() = 1380153600000
item.getDate().toDateTimeAtStartOfDay().getMillis() = 1380153600000
item.getDate() = {[email protected]}"2013-09-26"
new java.sql.Date(item.getDate().getLocalMillis()).getTime() = 1380153600000
new java.util.Date(item.getDate().getLocalMillis()) = {[email protected]}"Wed Sep 25 20:00:00 EDT 2013"
new java.util.Date(item.getDate().getLocalMillis()).getTime() = 1380153600000

Ответ 1

Правильные преобразования:

    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());
    }

Я использую это в своей логике помощника DAO. В JDBC вы должны сделать

 public static final Calendar calendarUTC = Calendar.getInstance(
       TimeZone.getTimeZone("UTC"));

 d = rs.getDate(i, calendarUTC);

И то же самое для установщика.

Ответ 2

У вас есть локальная дата joda

LocalDate loc = //...  

Вы можете преобразовать его в java.sql.Date с независимостью зоны, следующими способами:

Date date = new Date(loc .getYear() - 1900, loc .getMonthOfYear() - 1, loc .getDayOfMonth());

или

Date date = Date.valueOf(l.toString());

Ответ 3

Если вы нашли этот вопрос, выполнив поиск, как конвертировать Java 8 LocalDate, вот как вы это делаете:

public static Date valueOf (LocalDate date)

Получает экземпляр Date из объекта LocalDate с тем же год, месяц и день месяца, как данный LocalDate. если LocalDate интерпретируется как локальная дата в местное время зона. Параметры: date - LocalDate to convertReturns: дата objectThrows: NullPointerException - если дата равна nullSince: 1.8

Пример:

Date sqlDate = Date.valueOf(localDateObject);

Ответ 4

Вам следует создать и использовать java.sql.Timestamp, а не java.sql.Date. По спецификации java.sql.Date не имеет элемента времени.

Преобразование LocalDate в метку времени:

Timestamp timestamp = new Timestamp(localDate.toDateMidnight().getMillis());

Чтобы преобразовать LocalDateTime в метку времени:

Timestamp timestamp = new Timestamp(localDateTime.toDateTime().getMillis());