Как конвертировать из java.sql.Timestamp в java.util.Date?

i.e. этот код

startDate = new Date(timestampValue.getTime));

дает мне:

2012-16-02 05:16:17

когда

System.out.println(timestampValue);

return:

2012-01-02 05: 16: 17.0

Ответ 1

Вместо Calendar следует использовать

Calendar start = Calendar.getInstance();
start.setTimeInMillis( timeStampValue.getTime() );

Ответ 2

Класс java.sql.TimeStamp продолжается от java.util.Date.

Вы можете напрямую назначить объект TimeStamp для ссылки Date:

TimeStamp timeStamp = //whatever value you have;
Date startDate = timestampValue;

Ответ 3

ТЛ; др

Instant instant = myResultSet.getObject( … , Instant.class ) ;

… Или, если ваш драйвер JDBC не поддерживает дополнительный Instant, он должен поддерживать OffsetDateTime:

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Избегайте java.util.Date и java.sql.Timestamp. Они были заменены классами java.time. В частности, класс Instant представляющий момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).

Различные значения → Неподтвержденная проблема

Чтобы обратиться к основной части вопроса: "Почему разные даты между объектами java.util.Date и java.sql.Timestamp, когда одно происходит от другого?"

Должна быть проблема с вашим кодом. Вы не опубликовали свой код, поэтому мы не можем точно определить проблему.

Во-первых, это строковое значение, которое вы показываете для значения java.util.Date, не было получено из его метода toString умолчанию, поэтому вы, очевидно, выполняли дополнительные операции.

Во-вторых, когда я запускаю похожий код, я действительно получаю одинаковые значения даты и времени.

Сначала создайте объект java.sql.Timestamp.

// Timestamp
long millis1 =  new java.util.Date().getTime();
java.sql.Timestamp ts = new java.sql.Timestamp(millis1);

Теперь извлеките счетчик миллисекунд с начала эпохи, чтобы создать экземпляр объекта java.util.Date.

// Date
long millis2 = ts.getTime();
java.util.Date date = new java.util.Date( millis2 );

Дамп значения в консоль.

System.out.println("millis1 = " + millis1 );
System.out.println("ts = " + ts );
System.out.println("millis2 = " + millis2 );
System.out.println("date = " + date );

Когда беги.

millis1 = 1434666385642
ts = 2015-06-18 15:26:25.642
millis2 = 1434666385642
date = Thu Jun 18 15:26:25 PDT 2015

Таким образом, код, показанный в Вопросе, действительно является правильным способом преобразования из java.sql.Timestamp в java.util.Date, хотя вы потеряете данные наносекунд.

java.util.Date someDate = new Date( someJUTimestamp.getTime() ); 

Различные форматы строкового вывода

Обратите внимание, что выходные данные методов toString имеют другой формат, как описано в документации. Java.sql.Timestamp соответствует формату SQL, аналогичному формату ISO 8601, но без буквы T в середине.

Игнорировать наследование

Как уже говорилось в комментариях к другим Ответам и Вопросу, вы должны игнорировать тот факт, что java.sql.Timestamp наследуется от java.util.Date. В документе jsTimestamp четко указано, что вы не должны рассматривать одно как подтип другого: (выделено мной)

Из-за различий между классом Timestamp и классом java.util.Date, упомянутых выше, рекомендуется, чтобы код не просматривал значения Timestamp в общем случае как экземпляр java.util.Date. Отношения наследования между Timestamp и java.util.Date действительно обозначают наследование реализации, а не наследование типов.

Если вы игнорируете рекомендации Java-команд и придерживаетесь такого взгляда, одна из важнейших проблем заключается в том, что вы потеряете данные: любая микросекунда или наносекунда, которая может исходить из базы данных, теряется, поскольку Date имеет разрешение только в миллисекундах.

По сути, все старые классы даты и времени из ранней Java - большой беспорядок: java.util.Date, juCalendar, java.text.SimpleDateFormat, java.sql.Timestamp/.Date/.Time. Они были одними из первых доблестных попыток в отрасли с указанием даты и времени, но в конечном итоге они потерпели неудачу. В частности, здесь java.sql.Timestamp - это java.util.Date с нанесенными наносекундами; это взломать, не очень хороший дизайн.

java.time

Избегайте старых классов даты и времени, связанных с ранними версиями Java.

Вместо этого используйте, по возможности, пакет java.time (Tutorial), встроенный в Java 8 и более поздние версии.

Основы java.time… Instant - это момент времени на UTC. Примените часовой пояс (ZoneId), чтобы получить ZonedDateTime.

Пример кода с использованием java.time начиная с Java 8. С драйвером JDBC, поддерживающим JDBC 4.2 и более поздние версии, вы можете напрямую обмениваться классами java.time с вашей базой данных; нет необходимости в старых классах.

Instant instant = myResultSet.getObject( … , Instant.class) ;  // Instant is the raw underlying data, an instantaneous point on the time-line stored as a count of nanoseconds since epoch.

Вы можете настроить часовой пояс, отличный от UTC.

ZoneId z = ZoneId.of( "America/Montreal" );  // Always make time zone explicit rather than relying implicitly on the JVMs current default time zone being applied.
ZonedDateTime zdt = instant.atZone( z ) ;

Выполните свою бизнес-логику. Здесь мы просто добавляем день.

ZonedDateTime zdtNextDay = zdt.plusDays( 1 ); // Add a day to get "day after".

На последнем этапе, если это абсолютно необходимо, преобразуйте его в файл java.util.Date для обеспечения совместимости.

java.util.Date dateNextDay = Date.from( zdtNextDay.toInstant( ) );  // WARNING: Losing data (the nanoseconds resolution).

Дамп на консоль.

System.out.println( "instant = " + instant );
System.out.println( "zdt = " + zdt );
System.out.println( "zdtNextDay = " + zdtNextDay );
System.out.println( "dateNextDay = " + dateNextDay );

Когда беги.

instant = 2015-06-18T16:44:13.123456789Z
zdt = 2015-06-18T19:44:13.123456789-04:00[America/Montreal]
zdtNextDay = 2015-06-19T19:44:13.123456789-04:00[America/Montreal]
dateNextDay = Fri Jun 19 16:44:13 PDT 2015

Конверсии

Если вы должны использовать устаревшие типы для взаимодействия со старым кодом, который еще не обновлен для java.time, вы можете выполнить преобразование. Используйте новые методы, добавленные к старым классам java.util.Date и java.sql. * Для конвертации.

Instant instant = myJavaSqlTimestamp.toInstant() ;

…а также…

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;

См. Учебное пособие, Устаревший код даты и времени, для получения дополнительной информации о конверсиях.

Дробная секунда

Помните о разрешении доли секунды. Преобразование из наносекунд в миллисекунды означает потенциальную потерю некоторых данных.


О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, и SimpleDateFormat.

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений. Спецификация JSR 310.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*.

Где взять классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и другие.

Ответ 4

Проблема, вероятно, связана с тем, что Date устарела.

Рассмотрим использование

java.util.Calendar

или

Joda-Time

Изменить 2015:

Java 8 и более поздние версии встроены в новый пакет java.time, который похож на Joda-Time.

Ответ 5

public static Date convertTimestampToDate(Timestamp timestamp)  {
        Instant ins=timestamp.toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant();
        return  Date.from(ins);
}

Ответ 6

Новый способ Java 8 - Date.from(timestamp.toInstant()). См. Мой аналогичный ответ в другом месте.

Ответ 7

java.sql.ResultSet rs;
//fill rs somehow
java.sql.Timestamp timestamp = rs.getTimestamp(1); //get first column
long milliseconds = timestamp.getTime() + (timestamp.getNanos() / 1000000);
java.util.Date date = return new java.util.Date(milliseconds);