at_yasu's blog

ロード的なことを

NSDate の compare: に関するメモ書き

NSDate の時間を比較する時、compare: を使いますが、NSOrderedSame を返さない気配。


検証プログラム

void
fn (NSString* sel,NSDate* olddate,NSDate* fndate)
{
        SEL slt = NSSelectorFromString(sel);
        NSDate* ch = [olddate performSelector:slt
                                   withObject:fndate];
        NSLog(@"olddate[%@] %@ fndate[%@] => %@",
                olddate, sel, fndate, ch);
}

void
NSDateCompareResultOutput(NSComparisonResult result, NSDate* date1, NSDate* date2)
{
        NSString* str = @"";
        if (result == NSOrderedSame) str = @"Same";
        else if (result == NSOrderedDescending) str = @"Descending";
        else if (result == NSOrderedAscending) str = @"Ascending";
        else str = @"unknown";

        NSLog(@"date1[%@] date2[%@] => %@", date1, date2, str);
}

void
nsdateTest()
{
        NSDate* olddate = [NSDate date];
        NSDate* fndate = [NSDate date];
        NSDate* fatherdate = [NSDate dateWithTimeIntervalSinceNow:-120];
        NSDate* newdate = [NSDate dateWithTimeIntervalSinceNow:120];

        fn(@"earlierDate:", olddate, fndate);
        fn(@"laterDate:", olddate, fndate);
        fn(@"earlierDate:", olddate, newdate);
        fn(@"laterDate:", olddate, newdate);
        fn(@"earlierDate:", olddate, fatherdate);
        fn(@"laterDate:", olddate, fatherdate);

        NSDateCompareResultOutput([olddate compare:fndate], olddate, fndate);
        NSDateCompareResultOutput([olddate compare:newdate], olddate, newdate);
        NSDateCompareResultOutput([olddate compare:fatherdate], olddate, fatherdate);
}


結果

2010-05-30 15:15:11.470 hellow[3571:903] olddate[2010-05-30 15:15:11 +0900] earlierDate: fndate[2010-05-30 15:15:11 +0900] => 2010-05-30 15:15:11 +0900
2010-05-30 15:15:11.472 hellow[3571:903] olddate[2010-05-30 15:15:11 +0900] laterDate: fndate[2010-05-30 15:15:11 +0900] => 2010-05-30 15:15:11 +0900
2010-05-30 15:15:11.473 hellow[3571:903] olddate[2010-05-30 15:15:11 +0900] earlierDate: fndate[2010-05-30 15:17:11 +0900] => 2010-05-30 15:15:11 +0900
2010-05-30 15:15:11.475 hellow[3571:903] olddate[2010-05-30 15:15:11 +0900] laterDate: fndate[2010-05-30 15:17:11 +0900] => 2010-05-30 15:17:11 +0900
2010-05-30 15:15:11.476 hellow[3571:903] olddate[2010-05-30 15:15:11 +0900] earlierDate: fndate[2010-05-30 15:13:11 +0900] => 2010-05-30 15:13:11 +0900
2010-05-30 15:15:11.478 hellow[3571:903] olddate[2010-05-30 15:15:11 +0900] laterDate: fndate[2010-05-30 15:13:11 +0900] => 2010-05-30 15:15:11 +0900
2010-05-30 15:15:11.479 hellow[3571:903] date1[2010-05-30 15:15:11 +0900] date2[2010-05-30 15:15:11 +0900] => Ascending
2010-05-30 15:15:11.480 hellow[3571:903] date1[2010-05-30 15:15:11 +0900] date2[2010-05-30 15:17:11 +0900] => Ascending
2010-05-30 15:15:11.482 hellow[3571:903] date1[2010-05-30 15:15:11 +0900] date2[2010-05-30 15:13:11 +0900] => Descending

olddate == fndate = NSOrderedSame を期待してたのが、NSOrderedAscending を返します。ですので、NSOrderedSame は isEqualToDate: を使うようにした方が良さそうです。
一方の NSOrderedAscending は、 ![date isEqualToDate:hoge] && [date compare:hoge] == NSOrderedAscending で比較する必要有り。



追加:
nsdateTest関数内にある、「earlierDate:」と「laterDate:」は、「時間が若い方」と「時間が経っている方」を返す関数なので、それを使うのも手の一つ。