Подтвердить что ты не робот

Ошибка java.sql.Timestamp сравнения?

Здравствуйте, у меня есть фрагмент кода, подобный этому:

Date d1 = new java.sql.Timestamp(new Date().getTime());
Thread.sleep(10);
Date d2 = new java.sql.Timestamp(new Date().getTime());
System.out.println("Date1: " + d1);
System.out.println("Date2: " + d2);
System.out.println("Comparing times d1.t < d2.t: " + (d1.getTime() < d2.getTime()));
System.out.println("Comparing dates d1.before(d2): " + (d1.before(d2)));

Результат выглядит следующим образом:

Date1: 2013-03-26 11:04:01.093
Date2: 2013-03-26 11:04:01.103
Comparing times d1.t < d2.t: true
Comparing dates d1.before(d2): false

Что не так с этим классом java.sql.Timestamp?

Да, я это видел:

Примечание. Этот тип является составной частью java.util.Date и отдельной наносекундной стоимостью. В компоненте java.util.Date хранятся только целые секунды. Дробные секунды - нано - разделены. Метод Timestamp.equals(Object) никогда не возвращает true, когда передается значение типа java.util.Date, потому что компонент nanos даты неизвестен. В результате метод Timestamp.equals(Object) не является симметричным относительно метода java.util.Date.equals(Object). Кроме того, метод hashcode использует базовую реализацию java.util.Date и поэтому не включает в себя вычисления nos.

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

Но это для отношения Date ↔ Timestamp.

В моем примере у меня есть только Timestamps, и все же поведение неожиданно.

UPDATE: ANSWER

Причина этого в том, что метод before() перегружен, а не переопределяется в java.sql.Timestamp. Я ожидал "переопределения" поведения. Правильный способ сравнения временных меток состоит в том, чтобы иметь переменные Timestamp, а не Dates.

Это все еще плохое дизайнерское решение в ядре Java, поскольку наследование должно означать Timestamp is-Date, без штрафов и исключений.

4b9b3361

Ответ 1

Попробуйте использовать Timestamp вместо Date, и он будет работать.

Timestamp d1 = new java.sql.Timestamp(new Date().getTime());

Timestamp и Date оба имеют собственную реализацию метода before. Проверьте его.

Ответ 2

Ну, это похоже на недооцененную функцию.

Методы before и after Timestamp, по-видимому, сравниваются со вторым, но не учитывают часть миллисекунд. Попробуйте запустить его, пока оба Timestamp не упадут в разные секунды, и сравнение будет работать как ожидалось (увеличьте сон до 500, чтобы сделать его проще).

Кстати, метод compareTo учитывает миллисекунды, поэтому вы можете использовать это.

Ответ 3

Если вы вызываете метод Timestamp.before(Timestamp), вы получите ожидаемый результат.

Но, по-видимому, использование Timestamp как Date будет бесполезным. Вы должны использовать Timestamp как Timestamp статически.

Ответ 4

Как упоминалось здесь

timestamp - это тонкая оболочка

Временная метка просто добавляет возможность удерживать значение дробных секунд SQL TIMESTAMP (с точностью до наносекунды, где возникает проблема в вашем случае)