ТЛ; др
Используйте современные java.time классы, никогда не ужасные устаревшие классы даты и времени.
Instant
.ofEpochMilli( 1_532_654_534_390L )
.isAfter(
LocalDateTime
.parse(
"2018-07-27 01:22:14.077"
.replace( " " , "T" )
)
.atOffset(
ZoneOffset.UTC
)
.toInstant()
)
Док говорит: не используйте Timestamp
объект как Date
Ваш код:
Date date2 = new Timestamp… // Violates class documentation.
… нарушает договор, установленный в документации класса.
Из-за различий между классом Timestamp и классом java.util.Date, упомянутых выше, рекомендуется, чтобы код не просматривал значения Timestamp в общем случае как экземпляр java.util.Date. Отношения наследования между меткой времени и java.util.Date действительно обозначают наследование реализации, а не наследование типов.
Док отмечает, что, хотя java.sql.Timestamp
технически наследуется от java.util.Date
, вам предписано игнорировать этот факт наследования. Вы не должны использовать Timestamp
объект как Date
. Ваш код делает именно то, что доктор сказал вам , а не .
Конечно, эта политика "притворяйся не подклассом" - это смехотворно плохой дизайн класса. Этот хак является одной из многих причин, по которым никогда не используют эти классы .
Поведение, которое вы видели относительно несоответствия долей секунды и наносекунд миллисекунд, задокументировано:
Примечание. Этот тип является составной частью java.util.Date и отдельного значения наносекунд. В компоненте java.util.Date хранятся только целые секунды. Дробные секунды - нано - разделены. Метод Timestamp.equals (Object) никогда не возвращает true, если передан объект, который не является экземпляром java.sql.Timestamp, поскольку компонент nanos даты неизвестен. В результате метод Timestamp.equals (Object) не является симметричным относительно метода java.util.Date.equals (Object). Кроме того, метод hashCode использует базовую реализацию java.util.Date и, следовательно, не учитывает в своих вычислениях nanos.
java.time
Вы используете заведомо ужасные классы. Проблема, которую вы обнаружили, связана с их ужасным дизайном, который использовал плохие хаки. Не пытайтесь понять эти классы; просто избегайте их полностью .
Эти устаревшие классы были вытеснены несколько лет назад классами java.time .
Разбор вашей входной строки.
LocalDateTime ldt = LocalDateTime.parse( "2018-07-27 01:22:14.077".replace( " " , "T" ) ; // Without a time zone or offset, this value has no specific meaning, is *not* a point on the timeline.
Очевидно, вы точно знаете, что входная строка неявно представляла момент в UTC.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ; // Assign an offset-from-UTC to give the date and time a meaning as an actual point on the timeline.
Разобрать другой ввод, по-видимому, отсчет миллисекунд с первого момента 1970 года в UTC. Класс Instant
является более базовым, чем OffsetDateTime
, момент в UTC, всегда UTC по определению.
Instant instant = Instant.ofEpochMilli( 1_532_654_534_390L ) ; // Translate a count of milliseconds from 1970-01-01T00:00:00Z into a moment on the timeline in UTC.
Сравнить.
Boolean stringIsAfterLong = odt.toInstant().isAfter( 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
и more .