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
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
Вместо Calendar следует использовать
Calendar start = Calendar.getInstance();
start.setTimeInMillis( timeStampValue.getTime() );
Класс java.sql.TimeStamp
продолжается от java.util.Date
.
Вы можете напрямую назначить объект TimeStamp
для ссылки Date
:
TimeStamp timeStamp = //whatever value you have;
Date startDate = timestampValue;
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.
Вместо этого используйте, по возможности, пакет 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 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
и другие.
Проблема, вероятно, связана с тем, что Date устарела.
Рассмотрим использование
java.util.Calendar
или
Изменить 2015:
Java 8 и более поздние версии встроены в новый пакет java.time, который похож на Joda-Time.
public static Date convertTimestampToDate(Timestamp timestamp) {
Instant ins=timestamp.toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant();
return Date.from(ins);
}
Новый способ Java 8 - Date.from(timestamp.toInstant())
. См. Мой аналогичный ответ в другом месте.
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);
Timestamp - это дата: https://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html
java.lang.Object
java.util.Date
java.sql.Timestamp