Каков правильный путь от 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());