英文:
Same dates comparing in Java returning -1
问题
try {
String hql = "SELECT taskDate FROM TaskFutureDates t WHERE t.taskId = :taskId";
List<java.sql.Date> result = em.createQuery(hql).setParameter("taskId", taskId).getResultList();
java.sql.Date currentDate = new Date(new java.util.Date().getTime());
if (result.size() != 0) {
for (java.sql.Date date : result) {
if (date.compareTo(currentDate) >= 0) {
System.err.println("CAST= " + (Date) date);
return (java.sql.Date) date;
}
}
}
} catch (Exception e) {
// TODO: handle exception
//System.err.println(e);
}
return null;
}
比较两个日期时出现错误的情况:
-
当我比较不同日期时,我得到了 -1:
例如:
09/04/2020
10/04/2020 -
当日期相同时,我得到了 -1:
例如:
10/04/2020
10/04/2020
在第二种情况中,我应该得到 0,为什么结果是 -1?
英文:
try {
String hql = "SELECT taskDate FROM TaskFutureDates t WHERE t.taskId= : taskId";
List<java.sql.Date> result = em.createQuery(hql).setParameter("taskId", taskId).getResultList();
java.sql.Date currentDate =new Date(new java.util.Date().getTime());
if (result.size() != 0) {
for(java.sql.Date date: result) {
if(date.compareTo(currentDate)>=0) {
System.err.println("CAST= "+(Date) date);
return (java.sql.Date) date;
}
}
}
} catch (Exception e) {
// TODO: handle exception
//System.err.println(e);
}
return null;
}
when I am comparing the two dates I am getting error scenarios
1.when I am comparing alternative days I am getting -1<br/>
eg<br/>
09/04/2020<br/>
10/04/2020
- when the date is same I am getting -1
<br/>
eg <br/>
10/04/2020<br/>
10/04/2020
in the 2nd scenario, I should get 0 why the result is -1?
答案1
得分: 2
从compareTo文档中:
> 如果此日期早于日期参数,则为小于0的值
today()(= 上一次午夜)或可能是来自您的表的任何日期都小于now()(包括当前时间)
英文:
from the compareTo doc:
> a value less than 0 if this Date is before the Date argument
today() (= last midnight) or probably any date from your table is less than now() (which includes the current time)
答案2
得分: 1
虽然 java.sql.Date
应该表示日期,但实际上它仍然是对纪元毫秒的薄包装。它不会截断它们。因此,两个相同日期的 java.sql.Date
值仍然可以具有两个不同的纪元毫秒值(即检查 getTime()
的结果),因此它们不会比较相同。
java.sql.Date
构造函数(Date(long)
)的实现如下:
public Date(long date) {
// 如果毫秒日期值包含时间信息,则将其屏蔽。
super(date);
}
与注释相反,没有什么被屏蔽掉。这可能是因为 java.sql.Date
对默认的 JVM 时区很敏感,试图将其屏蔽只会让事情变得更加复杂。
无论如何,自从 Java 8 / JDBC 4.2 起,最好使用 java.time.LocalDate
而不是 java.sql.Date
。
如果你无法完全切换到使用 LocalDate
,我建议至少使用以下方式:
LocalDate currentDate = LocalDate.now();
//...
if (date.toLocalDate().compareTo(currentDate) >= 0) {
// ...
}
或者 - 如 Basil Bourque 的答案 所示 - 使用专门的比较方法,如 isAfter
、isBefore
和 isEqual
。
英文:
Although java.sql.Date
is supposed to be a date, it actually is still a thin wrapper around epoch milliseconds. It doesn't truncate them. So two java.sql.Date
values that are the same date, can still have two different epoch milliseconds values (ie check the getTime()
result), and as a result they won't compare identical.
The implementation of the java.sql.Date
constructor (Date(long)
) is:
public Date(long date) {
// If the millisecond date value contains time info, mask it out.
super(date);
}
Contrary to the comment, nothing is masked out. This is probably because java.sql.Date
is sensitive to the default JVM time zone, and trying to mask it out would only complicate things.
In any case, since Java 8 / JDBC 4.2, it would be better to use java.time.LocalDate
instead of java.sql.Date
.
If you can't fully switch to using LocalDate
, I would recommend at least using:
LocalDate currentDate = LocalDate.now();
//...
if (date.toLocalDate().compareTo(currentDate) >= 0) {
// ...
}
Or - as shown in the answer by Basil Bourque - use the specialized comparison methods like isAfter
, isBefore
and isEqual
.
答案3
得分: 1
# tl;dr
使用现代的 *java.time* 类来检索和比较存储的日期值与今天的日期。
myResultSet.getObject( … , LocalDate.class ).isAfter( LocalDate.now( "Africa/Tunis" ) )
# 详情
正如 [Rotteveel 给出的正确答案](https://stackoverflow.com/a/61137310/642706) 解释的那样,你不应该使用糟糕的 `java.sql.Date` 类。那个类多年前就被现代的 *java.time* 类取代了,具体来说,就是 `java.time.LocalDate`。
从 JDBC 4.2 开始,我们可以用数据库交换 *java.time* 对象。对于类似于标准 SQL 类型 `DATE` 的列,可以使用 `setObject`、`updateObject` 和 `getObject` 来交换 `LocalDate` 对象。
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
要获取今天的日期需要一个时区。对于任何给定的时刻,日期在全球范围内会根据时区而变化。因此,虽然在日本东京可能是“明天”,但在美国俄亥俄州托莱多可能同时是“昨天”。
如果不指定时区,JVM 的当前默认时区会隐式地应用。
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalDate today = LocalDate.now( z ) ;
使用 `isEqual`、`isBefore` 和 `isAfter` 方法进行比较。
Boolean isFuture = ld.isAfter( today ) ;
英文:
tl;dr
Use modern java.time classes to retrieve and compare stored date values against today’s date.
myResultSet.getObject( … , LocalDate.class ).isAfter( LocalDate.now( "Africa/Tunis" ) )
Details
As the correct Answer by Rotteveel explained, you should not be using the terrible class java.sql.Date
. That class was years ago supplanted by the modern java.time classes. Specifically, java.time.LocalDate
.
As of JDBC 4.2, we can exchange java.time objects with the database. For columns of a type akin to the standard-SQL type DATE
, use setObject
, updateObject
, and getObject
to exchange LocalDate
objects.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
To get today’s date requires a time zone. For any given moment, the date varies around the globe by time zone. So while it may be “tomorrow” in Tokyo Japan, it may simultaneously be “yesterday” in Toledo Ohio US.
If you do not specify a time zone, the JVM’s current default time zone is applied implicitly.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalDate today = LocalDate.now( z ) ;
Compare using isEqual
, isBefore
, and isAfter
methods.
Boolean isFuture = ld.isAfter( today ) ;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论