tags:

views:

161

answers:

5

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?

A: 

here

this ought to help.

sorry.. Deprecated.... but something like that.

iEisenhower
`java.sql.Time` has entirely different purposes.
BalusC
yeah. im new to programming. never answered before. not a very good first time entry though :( sorry i said, sorry i am.
iEisenhower
@ikurtz: No need to apologize. Keep participating. We're all learning.
polygenelubricants
jajaja, Don't apologize, just let me complete your SO experience by letting you know what happens next. Introducing downvote.
OscarRyz
@Oscar: ja ja yeah lets hope no one is that cruel!
iEisenhower
No hard feelings :) `java.sql.Time` is just meant to be able to set a `java.util.Date` in a SQL database column of `TIME` type. You can't use it to get rid of the time part in the `java.util.Date`.
BalusC
A: 
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));
Ipsquiggle
+1  A: 

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.

polygenelubricants
+1 for comparator, -1 for deprecated methods, +1 for suckage.
BalusC
I used DateUtils.isSameDay(d1, d2) from commons-lang inside my comparator instead of all these ternary operators.
Roman
+3  A: 

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 
OscarRyz
I'd add a `clear()` before `setTime()` to avoid timezone issues. OT: Account merge? It was high time :)
BalusC
@BalusC added. Yep, I had two 10k accounts already so, I though a merge was in order.
OscarRyz
@BalusC i don't understand the need for clear()? doesn't setTime() reset everything?
james
@james: it's a "practice" which was teached me years ago. The calendar was previously littered of bugs of which most was fixed by explicitly calling `clear()` after `getInstance()`. It also depends on JVM used.
BalusC
A: 

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 );
}
ablaeul