当前位置: 首页 > 面试题库 >

在Java中将Date对象与TimeStamp进行比较

苏乐童
2023-03-14
问题内容

当我测试此代码时:

java.util.Date date = new java.util.Date();
java.util.Date stamp = new java.sql.Timestamp(date.getTime());

assertTrue(date.equals(stamp));
assertTrue(date.compareTo(stamp) == 0);
assertTrue(stamp.compareTo(date) == 0);
assertTrue(stamp.equals(date));

我期待一个真实,真实,真实,错误。因为这:

在java.sql.Timestamp的javadoc中,它指出:

注意:此类型是java.util.Date和单独的纳秒值的组合。仅整数秒存储在java.util.Date组件中。小数秒-纳米-
是分开的。传递值java.util.Date类型的值时,Timestamp.equals(Object)方法从不返回true,因为日期的nanos组件是未知的。结果,Timestamp.equals(Object)方法相对于java.util.Date.equals(Object)方法不对称。另外,hashcode方法使用底层的java.util.Date实现,因此在其计算中不包括nanos。

由于上述Timestamp类和java.util.Date类之间的差异,建议代码不要以java.util.Date的实例的形式一般性地查看Timestamp值。Timestamp和java.util.Date之间的继承关系实际上表示实现继承,而不是类型继承。

但是相反,我会得到一个真实,错误,真实,错误的信息。有任何想法吗?

编辑:当我用equals方法检查两个日期,但其中一个Date对象来自Hibernate类并进行调试时,出现此问题,我看到该对象包含一个TimeStamp。因此equals方法的评估结果为false,然后我发现了这一点: http
//mattfleming.com/node/141

但是,当我尝试代码时,会得到不同的结果…如果我不能同时使用equals和compareTo,那我应该用什么来检查2个日期是否相同?!


问题答案:

使用现代的 java.time 类,而不要使用那些麻烦的旧式日期时间类。

myPreparedStatement.setObject(
    … , 
    Instant.now()                // Capture the current moment in UTC.
)

设计不好的旧日期时间类

坦率地说,java.sql.Timestamp / .Date /
.Time类是一个hack,一个糟糕的hack。像java.util.Date/.Calendar一样,它们是错误的设计选择的结果。

应该尽可能简短地使用java.sql类型,仅用于将数据移入/移出数据库。请勿用于业务逻辑和进一步的工作。

java.time

旧的日期时间类已被内置在Java
8及更高版本中的java.time框架取代。这些新类由JSR 310定义,其灵感来自于非常成功的Joda-Time库,并由ThreeTen-Extra项目扩展。

最终,我们应该看到JDBC驱动程序已更新,可以直接与这些java.time类型一起使用。但是直到那一天,我们需要转换为java.sql类型或从java.sql类型转换为。对于此类转换,请调用添加到旧类中的新方法。

一个Instant是UTC时间线的分辨率了一下纳秒。

Instant instant = myJavaSqlTimestamp.toInstant();

要走另一个方向:

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

应用一个时区以获得壁钟时间。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

java.time类具有简洁明智的类设计。因此您可以按预期使用equalscompareTo。需要注意的是有偏移的,UTC或时区的班还提供isEqualisBeforeisAfter方法。这些方法通过考虑时间轴上的时刻及其时间顺序进行比较。该equalscompareTo方法也考虑偏移或时区。

最小化java.sql的使用,同时最大化java.time的使用,使问题的讨论变得毫无意义。

在Hibernate中,将转换器用于java.time。

JDBC 4.2

从JDBC 4.2和更高版本开始,您根本不需要使用旧类。您可以通过&方法直接与数据库交换 java.time
对象。getObject``setObject

myPreparedStatement.setObject( … , instant ) ;

和检索。

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

注意,许多数据库无法存储分辨率与 java.time中 使用的纳秒一样精细的 时刻
。您可能想要显式截断而不是让JDBC驱动程序隐式截断。

Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ; // Lop off any nanoseconds & microseconds, keeping only the milliseconds, to match limitations of database.

关于 java.time

java.time 框架是建立在Java
8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

现在处于维护模式的 Joda-
Time

项目建议迁移到java.time类。

要了解更多信息,请参见
Oracle教程 。并在Stack
Overflow中搜索许多示例和说明。规格为JSR 310。

您可以直接与数据库交换 java.time 对象。使用与JDBC
4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

  • Java SE 8Java SE 9Java SE 10 和更高版本
    • 内置的
    • 标准Java API的一部分,具有捆绑的实现。
    • Java 9添加了一些次要功能和修复。
  • Java SE 6Java SE 7
    • java.time的许多功能在 ThreeTen- Backport中都被反向移植到Java 6和7 。
  • 安卓系统
    • 更高版本的Android捆绑了java.time类的实现。
    • 对于早期的Android(<26), ThreeTenABP 项目改编了 ThreeTen-Backport (如上所述)。请参阅 如何使用ThreeTenABP…

ThreeTen-额外
项目与其他类扩展java.time。该项目是将来可能向java.time添加内容的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多。



 类似资料:
  • 我创建了一个,当调用变量为ISE时,它会读取相关数据的表。但是,如果我尝试将与另一个对象进行比较,无法正确读取。我想告诉脚本,如果现有CSV中的任何行与匹配,则不会将数据导出到CSV,换句话说,跳过CSV文件中的重复行。CSV可能有也可能没有多行。

  • 我有一个类赋值,我需要将一个目标排序到一个二叉树节点中,给定一个根,我需要将它与根进行比较,如果目标小于根的值,则将目标作为左子,或者如果目标大于根的值,则将目标作为右子。 我必须使用给定的方法头和参数,我的代码是这样编写的: 返回以下错误: java:109:错误:二进制运算符“<”的操作数类型不正确 我还尝试了compareTo方法,通过尝试类似于 返回以下错误: binarySearchTr

  • 问题内容: 我想比较两个字符串在Java中的相等性(如果一个或两个都可以),因此我不能简单地调用。什么是最好的方法? 编辑: 问题答案: 这是Java内部代码(在其他方法上)使用的:

  • 我想通过提供自定义顺序对包含不相关对象的列表进行排序。例如,我要排序的列表包含Animal类的对象。动物对象有一个名为type的对象,可以是猫、老鼠或狗。我有一个自定义订单鼠标 一种解决方案是手动检查类型的类(通过 instanceof)并在比较器中对顺序进行硬编码。但是,我有太多可以包含在 Animal 中的类(在本例中不仅包含三个类),因此这将产生大量的 if 案例。

  • 我刚刚违反了PMD中的CompareObject和Quals规则,因为我用“==”而不是equals()比较了两个对象引用,但我很难理解为什么这是一个问题,也找不到任何理由来解释这个限制。 我很欣赏这个东西。equals()比较引用,因此具有相同的效果,但我没有使用原始对象,因此我不能保证该方法不会在层次结构中的某个位置被重写。 我想做一个参考比较,我想确保这总是一个参考比较。为什么PMD要强迫我

  • 问题内容: 如何将RSS提要中的pubDate解析为java中的Date对象。 RSS Feed中的格式:2010年4月24日,星期六,格林尼治标准时间 我目前所拥有的: 但是此代码将引发ParseException并显示消息Unparseable date 问题答案: 您可以使用class定义要解析的日期格式: 此外,对于非英语的,在解析英语日期时,请确保使用以下内容: