在Java中使用TimeStamp比较Date对象 [英] Compare Date object with a TimeStamp in Java

查看:235
本文介绍了在Java中使用TimeStamp比较Date对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我测试这个代码:

  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,因为
date的nanos组件是未知的。因此,Timestamp.equals(Object)方法是
相对于java.util.Date.equals(Object)
方法不对称。此外,hashcode方法使用底层的java.util.Date
实现,因此在其
计算中不包括nanos。



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


但是我会得到一个真实的,虚假的,真实的,虚假的。任何想法?



编辑:当我用equals方法检查两个日期时出现这个问题,但是Date对象之一来自Hibernate类,调试我看到该对象包含一个TimeStamp。所以equals方法评估为false,那么我发现这一点: http://mattfleming.com/node/141



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

解决方案

旧的日期时间类设计不佳



更直截了当地,java.sql.Timestamp / .Date / .Time类是一个黑客,一个坏的黑客。像java.util.Date/.Calendar一样,它们是糟糕的设计选择的结果。



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



java.time



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



最终我们应该看到JDBC驱动程序已更新直接使用这些java.time类型。但直到那天,我们需要转换为/从java.sql类型转换。对于此类转化,请致电添加到旧类的新方法



即时 是UTC时间线上的一段时间,以纳秒秒的解决方案。

 即时即时= 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类有一个干净巧妙选择的类设计。所以你可以按照预期使用等于 compareTo 。请注意,从UTC或时区偏移的课程还提供 isEqual isBefore isAfter 方法。这些方法通过考虑时间轴上的时刻,按时间顺序比较。 等于 compareTo 方法也考虑偏移或时区。



最小化使用java.sql同时最大限度地利用java.time渲染问题的问题。



在Hibernate中,使用转换器进行java.time。



搜索堆栈溢出更多的例子和讨论。


When I test this code:

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));

I´ll be expecting a true, true, true, false. Because of this:

In the javadoc for java.sql.Timestamp, it states:

Note: This type is a composite of a java.util.Date and a separate nanoseconds value. Only integral seconds are stored in the java.util.Date component. The fractional seconds - the nanos - are separate. The Timestamp.equals(Object) method never returns true when passed a value of type java.util.Date because the nanos component of a date is unknown. As a result, the Timestamp.equals(Object) method is not symmetric with respect to the java.util.Date.equals(Object) method. Also, the hashcode method uses the underlying java.util.Date implementation and therefore does not include nanos in its computation.

Due to the differences between the Timestamp class and the java.util.Date class mentioned above, it is recommended that code not view Timestamp values generically as an instance of java.util.Date. The inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance.

But instead I´ll get a true, false, true, false. Any ideas?

EDIT: This problem appear when a I was checking two Dates with the equals method, but one of the Date object come from a Hibernate class and debugging I see that the object contains a TimeStamp. So the equals method evaluate to false, then I found this: http://mattfleming.com/node/141

But when I try the code I get different results...if I can´t use neither equals and compareTo, what I should use to check if 2 Dates are the same?!?!

解决方案

Old Date-Time Classes Poorly Designed

Put more bluntly, the java.sql.Timestamp/.Date/.Time classes are a hack, a bad hack. Like java.util.Date/.Calendar, they are the result of poor design choices.

The java.sql types should be used as briefly as possible, used only for transfer of data in/out of the database. Do not use for business logic and further work.

java.time

The old date-time classes have been replaced by the java.time framework built into Java 8 and later. These new classes are defined by JSR 310, inspired by the highly successful Joda-Time library, and extended by the ThreeTen-Extra project.

Eventually we should see JDBC drivers updated to work directly with these java.time types. But until that day we need to convert to/from java.sql types. For such conversions, call new methods added to the old classes.

An Instant is a moment on the timeline in UTC to a resolution of nanoseconds.

Instant instant = myJavaSqlTimestamp.toInstant();

To go the other direction:

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

Apply a time zone to get wall-clock time.

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

The java.time classes have a clean wisely-chosen class design. So you can use the equals and compareTo as expected. Note that the classes with an offset-from-UTC or time zone also offer isEqual, isBefore, and isAfter methods. These methods compare by considering moments on the timeline, their chronological order. The equals and compareTo methods also consider the offset or time zone.

Minimizing the use of java.sql while maximizing the use of java.time renders the Question’s issues moot.

In Hibernate, use converters for java.time.

Search Stack Overflow for many more examples and discussions.

这篇关于在Java中使用TimeStamp比较Date对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆