【问题标题】:How to compare java.sql.Timestamp and java.util.Date如何比较 java.sql.Timestamp 和 java.util.Date
【发布时间】:2017-10-08 12:56:16
【问题描述】:

我知道 java Date 的设计很糟糕,但直到今天我才知道。

我将日期保存到 DB,当我从 DB 获取它并与原始日期比较时,它告诉我它不同!

我写了一个看起来很奇怪的测试,但它通过了!

@Test
public void date_equals() {
    Date now = new Date();
    Timestamp timestamp = new Timestamp(now.getTime());

    assertFalse(timestamp.equals(now));
    assertTrue(now.equals(timestamp));

    assertTrue(timestamp.compareTo(now) == 0);
    assertFalse(now.compareTo(timestamp) == 0);

    assertTrue(timestamp.getTime() == now.getTime());
    assertTrue(now.getTime() == timestamp.getTime());
}

我注意到 java.sql.Timestamp 在纳秒方面与 Date 略有不同,我不在乎。

谁能告诉我如何在最佳实践中比较这两者? 我不想到处比较日期使用 getTime(),有没有通用库或其他方法可以做到这一点?

顺便说一句,我正在使用 JDK 6

【问题讨论】:

  • Timestamp 的 Javadoc 说 equals 方法不是对称的。我想如果您需要使用 equals,请确保在时间戳之前指定日期。
  • java.sql.Datejava.util.Date ?
  • @BasilBourque 必须是 java.util.Date,因为他使用的是无参数构造函数。

标签: java mysql date java-6 sql-timestamp


【解决方案1】:

tl;博士

originalInstant.equals( 
    org.threeten.bp.DateTimeUtils.toInstant( mySqlTimestamp ) 
) 

避免使用旧的日期时间类

与最早版本的 Java 捆绑在一起的旧日期时间类一团糟,设计糟糕,黑客攻击也很笨拙。其中一个糟糕的技巧是让java.sql.Timestamp 成为java.util.Date 的子类,同时告诉你忽略继承这一事实。

引用the class doc(强调我的):

由于上面提到的 Timestamp 类和 java.util.Date 类之间的差异,建议代码不要将 Timestamp 值一般视为 java.util.Date 的实例。 Timestamp 和 java.util.Date 的继承关系实际上是实现继承,而不是类型继承。

你被告知要假装它们是相关的类。因此,您尝试比较每种类型的对象是不合适的。

数据丢失

Timestamp 的分辨率高达nanosecondsjava.util.Date 类仅限于 milliseconds。所以两者不会相等。

使用 java.time

改为使用 java.time 类。它们的大部分功能都可以作为 Java 6 的后向端口使用——见下文。

当您获得Timestamp 时,立即转换为 java.time 类型。在 Java 8 及更高版本中,您可以调用添加到这些旧类中的新方法进行转换。在 Java 6 和 7 的 ThreeTen-Backport 库中,使用 org.threeten.bp.DateTimeUtils.toInstant( Timestamp )

InstantUTC 时间线上的一个时刻,分辨率为nanoseconds

Instant instant = DateTimeUtils.toInstant( mySqlTimestamp ) ;

现在与您的原始Instant 进行比较。

boolean isOriginal = originalInstant.equals( instant ) ;

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

从哪里获得 java.time 类?

【讨论】:

  • 该死,在你最近的编辑之后,我想再次投票。
【解决方案2】:

【讨论】:

  • OP 说他已经尝试过了,但没有得到想要的结果。
  • 这对我有用 -- timestamp.equals(date) 返回 falsetimestamp.compareTo(date) 返回 0
猜你喜欢
  • 2014-07-18
  • 2021-05-03
  • 2012-05-24
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 2011-08-17
相关资源
最近更新 更多