说你的两个日期有不同的格式并不准确。 Date 没有格式。你看到你打印的日期是他们toString方法的返回值。
相反,您的日期有不同的运行时类型。 d1 是java.util.Date 的一个实例,它的toString 方法生成Sat May 25 10:00:00 WET 2019 格式。 d2又是java.sql.Date的一个实例。它是java.util.Date 的子类,因此可以分配给这种类型的变量。 java.sql.Date.toString() 生成格式 2019-05-25。但是,子类(继承)关系是一种你不应该在代码中依赖的技巧。
不过,继承黑客只是这两个类的众多设计问题之一。幸运的是,两者都存在更新和更现代的替代品。对于java.util.Date,现代Instant 类是最直接对应的类型,但具体使用哪一种取决于您更精确的要求。对于java.sql.Date,它更简单,使用LocalDate。 Instant 和 LocalDate 都是现代 Java 日期和时间 API java.time 的一部分。
所以看看你是否可以用 Instant 或 java.time 中的其他合适的现代类型替换 bean.fooDate。同样,看看您是否可以让fooEntity.getFooDate() 返回LocalDate。 Hibernate 应该很乐意为您处理 LocalDate 而不是 Date(除非您的 Hibernate 版本非常旧)。
在任何情况下,Srinivasan Sekar 都是正确的,您应该将您从每个获得的任何类型转换为 LocalDate 以仅比较日期而不是小时、分钟和秒。 LocalDate 就是这样:一个没有时间的日期。
假设您从bean.fooDate 获得Instant。那么转换为:
LocalDate localDate1 = bean.fooDate.atZone(ZoneId.of("Africa/El_Aaiun")).toLocalDate();
请务必指定适当的时区。
如果您无法避免老式的Date,那么 Srinivasan Sekar 的答案中的转换是正确的:
LocalDate localDate1 = bean.fooDate
.toInstant()
.atZone(ZoneId.of("Africa/El_Aaiun"))
.toLocalDate();
对于fooEntity.getFooDate() 的情况,如果你能得到上面提到的LocalDate,你就完成了。如果只能得到Date,首先检查方法是否声明为返回java.util.Date 或java.sql.Date。它可能取决于声明方法的文件中使用的导入。 java.sql.Date 的情况很简单(尽管不幸的是不能保证总是给出正确的日期):
LocalDate localDate2 = fooEntity.getFooDate().toLocalDate();
如果声明的返回类型是java.util.Date,您可以只在上面添加一个强制转换,因为看起来实际返回的对象是java.sql.Date。不过,首先测试您的假设会更安全:
LocalDate localDate2;
Date d2 = fooEntity.getFooDate();
if (d2 instanceof java.sql.Date) {
localDate2 = ((java.sql.Date) fooEntity.getFooDate()).toLocalDate();
} else {
localDate2 = d2.toInstant()
.atZone(ZoneId.of("Africa/El_Aaiun"))
.toLocalDate();
}
您会发现,在第二种情况下,我使用的转换与上述相同。
比较生成的LocalDate 变量:
if (localDate1.isEqual(localDate2)) {
System.out.println("Same date");
} else {
System.out.println("Different dates");
}
LocalDate 也有方法 isBefore 和 isAfter 以防您需要确定哪个更早。
链接: Oracle tutorial: Date Time 解释如何使用 java.time。