在Java中将Date对象与TimeStamp进行比较
当我测试此代码时:
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个日期是否相同?!
回答:
tl; dr
使用现代的 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类具有简洁明智的类设计。因此您可以按预期使用equals
和compareTo
。需要注意的是有偏移的,UTC或时区的班还提供isEqual
,isBefore
和isAfter
方法。这些方法通过考虑时间轴上的时刻及其时间顺序进行比较。该equals
和compareTo
方法也考虑偏移或时区。
最小化java.sql的使用,同时最大化java.time的使用,使问题的讨论变得毫无意义。
在Hibernate中,将转换器用于java.time。
回答:
从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.Date
,Calendar
,和SimpleDateFormat
。
现在处于维护模式的 Joda-
Time
项目建议迁移到java.time类。
要了解更多信息,请参见
Oracle教程 。并在Stack
Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用与JDBC
4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取java.time类?
- , , 和更高版本
- 内置的
- 标准Java API的一部分,具有捆绑的实现。
- Java 9添加了一些次要功能和修复。
- 和
- java.time的许多功能在 Backport中都被反向移植到Java 6和7 。
- 更高版本的Android捆绑了java.time类的实现。
- 对于早期的Android(<26), 项目改编了 (如上所述)。请参阅 如何使用ThreeTenABP… 。
该
项目与其他类扩展java.time。该项目是将来可能向java.time添加内容的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
以上是 在Java中将Date对象与TimeStamp进行比较 的全部内容, 来源链接: utcz.com/qa/415524.html