2010-05-23 76 views
9

嗯,我想這已經被問了一千次,但由於某些原因,answeres真的不工作,或有其他問題,....比較NSDate的當天或前一天

反正這裏是我有「的工作「:

NSCalendar *calendar = [NSCalendar currentCalendar];  
    NSDate *currentDate = [NSDate date]; 
    NSDateComponents *comps = [[NSDateComponents alloc] init]; 
    // set tomorrow (0: today, -1: yesterday) 
    [comps setDay:0]; 
    NSDate *dateToday = [calendar dateByAddingComponents:comps toDate:currentDate options:0]; 
    [comps setDay:-1]; 
    NSDate *dateYesterday = [calendar dateByAddingComponents:comps toDate:currentDate options:0]; 
    [comps release]; 


NSString *todayString = [self.dateFormatter stringFromDate:dateToday] ; 
NSString *yesterdayString = [self.dateFormatter stringFromDate:dateYesterday] ; 
NSString *refDateString = [self.dateFormatter stringFromDate:info.date]; 

if ([refDateString isEqualToString:todayString]) 
{ 
    cell.title.text = @"Today"; 
} else if ([refDateString isEqualToString:yesterdayString]) 
{ 
    cell.title.text = @"Yesterday"; 
} else 
{ 
    cell.title.text = [self.dateFormatter stringFromDate:info.date]; 
} 

現在的問題(S):這似乎是一個awefull大量的代碼只是一個日期comparinson,有更簡單的方法

而最重要的問題是所有對象的釋放。正如可能猜到的,我在UITableViewController中使用了這個。我也有這些線在我的代碼:

//[calendar release]; 
//[currentDate release]; 
//[dateToday release]; 
//[dateYesterday release]; 
//[todayString release]; 
//[yesterdayString release]; 
//[refDateString release]; 

的問題是,一旦我取消註釋這些行之一,我的應用程序崩潰,我不知道爲什麼?!我希望有人能在這裏啓發我。

非常感謝。

+1

好了,最後一點很簡單:你不擁有任何這些對象,所以他們不是你的發佈。 comps是您分配的唯一對象。其他人將全部退回autoreleased或不打算被釋放。 – walkytalky 2010-05-23 23:02:25

+0

謝謝,很好的描述;) – elementsense 2010-05-24 00:48:01

回答

12

做到這一點最簡單的方法是隻比較日期的description

// Your dates: 
NSDate * today = [NSDate date]; 
NSDate * yesterday = [NSDate dateWithTimeIntervalSinceNow:-86400]; //86400 is the seconds in a day 
NSDate * refDate; // your reference date 

// 10 first characters of description is the calendar date: 
NSString * todayString = [[today description] substringToIndex:10]; 
NSString * yesterdayString = [[yesterday description] substringToIndex:10]; 
NSString * refDateString = [[refDate description] substringToIndex:10]; 

if ([refDateString isEqualToString:todayString]) 
{ 
    cell.title.text = @"Today"; 
} else if ([refDateString isEqualToString:yesterdayString]) 
{ 
    cell.title.text = @"Yesterday"; 
} else 
{ 
    cell.title.text = refDateString; 
} 

如果你想改變,你可以使用descriptionWithLocale:替代日期字符串的格式。

+15

不要依賴描述方法的結果。它主要用於調試目的,並不保證是持久的或可逆的。如果你想使用這種字符串比較方法,使用顯式的NSDateFormatter來生成你想要的確切字符串。但是,如果您可以比較由NSCalendar生成的組件,則這有點矯枉過正。 – 2011-10-23 09:44:34

+0

我得到的描述方法結果(在iOS 7.1中)以GMT格式提供日期,這意味着它將以GMT當前用戶所在時區的偏移量關閉。對我而言,這意味着今天開始提前6小時。 – dwsolberg 2014-03-19 16:25:47

-1

您可以使用isEqualToDate方法比較兩個NSDate對象,將返回一個bool(yes或no),告訴您日期是否相等。請參閱Apple Documentation

至於釋放對象 - 在Objective-C中的規則是,你只釋放在你的方法過程中分配內存的對象。您在代碼中專門爲內存分配的唯一對象是comps,因此它是您應該釋放的唯一對象 - 並且您已經這樣做了。爲你永遠不會分配的對象釋放內存可能是導致你的應用程序崩潰的原因。當實際分配這些對象的方法嘗試釋放這些對象或對它們的另一個引用嘗試訪問它們時,它們將觸發EXC_BAD_ACCESS錯誤,因爲您已經釋放它們!

所以,不要僅僅註釋掉這些版本行,將它們從腳本中刪除 - 不需要它們!

+1

'isEqualToDate:'在這裏不起作用。如果日期「完全相同」,則它只返回「YES」:「此方法檢測日期之間的亞秒差異。」 (來自課程參考。) – mohsenr 2010-05-23 23:45:50

6

我知道這是一個古老的問題,但我只是在做一些類似的事情,並加以處理。

首先,自iOS 4.0(和Mac OS 10.6),NSDateFormatter可以執行相對日期,這會自動爲您提供「今日」和「昨天」。

NSDateFormatter* formatter = [[NSDateFormatter alloc] init]; 
[formatter setTimeStyle:NSDateFormatterNoStyle]; 
[formatter setDateStyle:NSDateFormatterShortStyle]; 
[formatter setDoesRelativeDateFormatting:YES]; 

NSString* dateString = [formatter stringFromDate:[NSDate date]];  
NSLog(@"date = %@", dateString); 

,輸出:

2014-03-15 15:26:37.683 TestApp[1293:303] date = Today 

然而,OP是問如何比較的NSDate當天或前一天,這是我也想這樣做,相對日期格式一邊。以下是我想出了,作爲一個類別上NSDate實現:

@implementation NSDate (IsToday) 

- (BOOL) isToday 
{ 
    NSCalendar* calendar = [NSCalendar currentCalendar]; 

    // Components representing the day of our date. 
    NSDateComponents* dateComp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit 
              fromDate:self]; 
    NSDate* date = [calendar dateFromComponents:dateComp]; 

    // Components representing today. 
    NSDateComponents* todayComp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit 
               fromDate:[NSDate date]]; 
    NSDate* todayDate = [calendar dateFromComponents:todayComp]; 

    // If the dates are equal, then our date is today. 
    return [date isEqualToDate:todayDate]; 
} 

@end 

我想要做的是這樣的話,我可以顯示今天創造的東西的時間的原因,而今天沒有創建日期 - 類似於Mail.app顯示消息日期的方式。它看起來像這樣:

- (NSString*) postDateToString:(NSDate*)aDate 
{ 
    static NSDateFormatter* todayFormatter = nil; 
    if(todayFormatter == nil) { 
     todayFormatter = [[NSDateFormatter alloc] init]; 
     [todayFormatter setTimeStyle:NSDateFormatterShortStyle]; 
     [todayFormatter setDateStyle:NSDateFormatterNoStyle]; 
    } 

    static NSDateFormatter* notTodayFormatter = nil; 
    if(notTodayFormatter == nil) { 
     notTodayFormatter = [[NSDateFormatter alloc] init]; 
     [notTodayFormatter setTimeStyle:NSDateFormatterNoStyle]; 
     [notTodayFormatter setDateStyle:NSDateFormatterShortStyle]; 
     [notTodayFormatter setDoesRelativeDateFormatting:YES]; 
    } 

    NSDateFormatter* formatter = notTodayFormatter; 

    if([aDate isToday]) { 
     formatter = todayFormatter; 
    } 

    return [formatter stringFromDate:aDate]; 
} 
2

我可以建議使用這個開源項目: https://github.com/erica/NSDate-Extensions

您可以查看當前的方法:

+ (NSDate *) dateTomorrow 
+ (NSDate *) dateYesterday 
+0

這是一個很棒的延伸 - 感謝Kriv。 CocoaPod也支持:pod'NSDate-Extensions','〜> 0.0.1' – Fraser 2014-10-15 02:00:11