Reputation: 935
I am setting a color field based on how the dueDate
field compares to the current date. dueDate
is an SQL Date type. My problem is when I pass in the current date the Calendar.before()
method says the date is before the current date. My code is:
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;
}
}
I have set a breakpoint and compared dueDate
and today
and all of the information in the cdate
field for each object looks identical, but the dueDate.before(today)
still returns true. Any help would be appreciated!
Upvotes: 0
Views: 7390
Reputation: 1
Another way is to compare yyyy, mm, dd fields. If they are the same - dont use .after() nor .before() Simon Franz
Upvotes: 0
Reputation: 338574
The answer by marcospereira is correct. I'll add some general suggestions about revamping the code shown in the Question, and show the use of java.time.
Do not pass around java.sql types and perform business logic on them. Use java.sql only for transferring data in and out of the database. For java.sql.Timestamp/.Date/.Time immediately convert them to java.time objects. Then proceed with your business logic.
LocalDate due = myJavaSqlDate.toLocalDate();
Avoid the old date-time classes bundled with the earliest versions of Java such as java.util.Date/.Calendar. They are confusing, poorly designed, and troublesome.
In Java 8 and later, the old date-time class have been supplanted by the java.time framework. These new classes are a vast improvement. Inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project.
The code in the Question suggests that you want to work with date-only values such as java.sql.Date pretends to be. Yet you mix it with java.util.Calendar which represents a date and a time-of-day.
Above in this Answer you can the java.time.LocalDate
class. This class represents a date-only value without time-of-day nor time zone.
Time zone is crucial when dealing with date-only values. A date-only (without time-of-day) is inherently ambiguous. The date is not the same around the world at any given moment. A new day dawns earlier in the east. Minutes after midnight in Paris is still “yesterday” in Montréal.
So to determine “today” requires a time zone. If not specified, your JVM’s current default time zone is implicitly applied. Not good. Results may vary at runtime depending on settings of the host operating system and of the JVM. The default time zone can even be changed during runtime by any code in any thread of any app within the JVM.
So, better to specify the desired/expected time zone explicitly.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
Now compare to see if the due date has passed.
if( today.isAfter( due ) ) {
// Overdue.
}
Upvotes: 1
Reputation: 12214
Are you sure they are equal? Method equals
for Date
and Calendar
means they represents the same time value (millisecond offset from the Epoch). See the javadocs for Calendar.equals
method:
Compares this Calendar to the specified Object. The result is true if and only if the argument is a Calendar object of the same calendar system that represents the same time value (millisecond offset from the Epoch) under the same Calendar parameters as this object.
The before
method docs states that compareTo
is used to decide if a calendar instance is before another. And again, compareTo
is using millisecond precision. From the docs:
Compares the time values (millisecond offsets from the Epoch) represented by two Calendar objects.
The alternatives are:
clear
method on them and then set values (year, month, hourOfDay, minute, second) using the set
method.java.time.LocalDate
)Upvotes: 4