我根据dueDate
字段与当前日期的比较方式设置颜色字段。 dueDate
是SQL日期类型。我的问题是当我传递当前日期时Calendar.before()
方法说日期在当前日期之前。我的代码是:
private String getDateDueColor(Date dateDue) {
Calendar today = Calendar.getInstance();
today.setTime(new java.sql.Date(Calendar.getInstance().getTime().getTime()));
Calendar dueDate = Calendar.getInstance();
dueDate.setTime(dateDue);
if(dueDate.before(today)){
return RED;
}else{
return NORMAL;
}
}
我设置了一个断点并比较了dueDate
和today
,并且每个对象的cdate
字段中的所有信息看起来都相同,但dueDate.before(today)
仍然返回true 。任何帮助将不胜感激!
答案 0 :(得分:4)
你确定他们是平等的吗? equals
和Date
的方法Calendar
表示它们表示相同的时间值(距离Epoch的毫秒偏移量)。请参阅javadocs for Calendar.equals
method:
将此Calendar与指定的Object进行比较。当且仅当参数是同一日历系统的Calendar对象时,结果才为真,该对象在与此对象相同的Calendar参数下表示与Epoch相同的时间值(毫秒偏移)。
compareTo
compareTo
用于确定日历实例是否在另一个之前。同样,clear
使用的是毫秒精度。来自before
method docs states:
比较两个Calendar对象所代表的时间值(与Epoch的毫秒偏移量)。
替代方案是:
set
method并选择一种更能代表您想要的类型(可能是java.time API)java.time.LocalDate
。答案 1 :(得分:1)
answer by marcospereira是正确的。我将添加一些关于修改问题中显示的代码的一般性建议,并展示java.time的使用。
不要传递java.sql类型并对它们执行业务逻辑。仅使用java.sql将数据传入和传出数据库。对于java.sql.Timestamp / .Date /。时间立即将它们转换为java.time对象。然后继续您的业务逻辑。
LocalDate due = myJavaSqlDate.toLocalDate();
避免使用与最早版本的Java捆绑在一起的旧日期时间类,例如java.util.Date/.Calendar。它们令人困惑,设计糟糕,麻烦。
在Java 8及更高版本中,旧的日期时间类已被java.time框架取代。这些新类是巨大的改进。灵感来自Joda-Time,由JSR 310定义,并由ThreeTen-Extra项目扩展。
问题中的代码表明您希望使用java.sql.Date之类的仅限日期的值。然而,您将其与java.util.Calendar混合,后者代表日期和一个时间。
在本答案的上方,您可以java.time.LocalDate
课程。此类表示仅包含日期的值,没有时间或时区。
在处理仅限日期的值时,时区至关重要。仅限日期(没有时间)本质上是模棱两可的。在任何特定时刻,世界各地的日期都不一样。新的一天在东部早些时候开始。巴黎午夜过后几分钟仍在蒙特利尔“昨天”。
因此,确定“今天”需要一个时区。如果未指定,则隐式应用JVM的当前默认时区。不好。结果可能在运行时有所不同,具体取决于主机操作系统和JVM的设置。在运行期间,甚至可以通过JVM中任何应用程序的任何线程中的任何代码更改默认时区。
因此,最好明确指定所需/预期的时区。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
现在进行比较以查看截止日期是否已过去。
if( today.isAfter( due ) ) {
// Overdue.
}
答案 2 :(得分:0)
另一种方法是比较yyyy,mm,dd字段。如果它们是相同的 - 不要使用.after()和.before() 西蒙弗兰兹