I need to make map where Dates are keys. 2 date objects are equals if they have the same value of getTime()
method.
I'm interested only in year, month and day. How can I trim
unnecessary hours and minutes to get 'clear' dates?
I need to make map where Dates are keys. 2 date objects are equals if they have the same value of getTime()
method.
I'm interested only in year, month and day. How can I trim
unnecessary hours and minutes to get 'clear' dates?
long time1 = myDate1.getTime()/(1000*60*60*24);
long time2 = myDate2.getTime()/(1000*60*60*24);
if (time1 == time2)
// equal!
This pushes insignificant values below the decimal, then integer division truncates it, so only values significant at the Day level and higher are left.
If you want to make those dates again, just apply the offset back to the truncated values:
myDate1.setTime(time1 * (1000*60*60*24));
myDate2.setTime(time2 * (1000*60*60*24));
Use a custom Comparator<Date>
for a TreeMap<Date,V>
.
Comparator<Date> ymdComparator = new Comparator<Date>() {
@Override public int compare(Date d1, Date d2) {
return
d1.getYear() < d2.getYear() ? -1 :
d1.getYear() > d2.getYear() ? +1 :
d1.getMonth() < d2.getMonth() ? -1 :
d1.getMonth() > d2.getMonth() ? +1 :
d1.getDay() < d2.getDay() ? -1 :
d1.getDay() > d2.getDay() ? +1 :
0;
}
};
SortedMap<Date,V> map = new TreeMap<Date,V>(ymdComparator);
Oh, java.util.Date
sucks, use Joda Time, etc.
You can create a trim
method:
public static Date trim(Date date) {
Calendar cal = Calendar.getInstance();
cal.clear(); // as per BalusC comment.
cal.setTime( date );
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTIme();
}
And use it like:
map.put( trim( aDate ), xyz() );
...
map.get( trim( otherDate ));
Here's a complete working sample:
import java.util.Calendar;
import java.util.Date;
import static java.util.Calendar.*;
import static java.lang.System.out;
public class DateTest {
public static void main( String [] args ) throws InterruptedException {
Date date = new Date();
Thread.sleep(1);
Date other = new Date();
out.printf("equals? = %s, hashCode? = %s %n", (date.equals(other)), (date.hashCode() == other.hashCode()));
Date todayeOne = trim( date );
Date todayTwo = trim( date );
out.printf("equals? = %s, hashCode? = %s %n", (todayeOne.equals(todayTwo)), (todayeOne.hashCode() == todayTwo.hashCode()));
}
public static Date trim(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime( date );
cal.set(HOUR_OF_DAY, 0);
cal.set(MINUTE, 0);
cal.set(SECOND, 0);
cal.set(MILLISECOND, 0);
return cal.getTime();
}
}
output:
$ java DateTest
equals? = false, hashCode? = false
equals? = true, hashCode? = true
Just convert your Date
objects to be equal, if the have the same year, month and day:
public static Date convertDate(Date oldDate) {
final long oneDay = 1000 * 60 * 60 * 24;
long newDate = oldDate.getTime() / oneDay;
return new Date( newDate * oneDay );
}