2010-05-23 13 views
9

Nun, ich denke, das tausendmal gefragt wurde, aber aus irgendeinem Grund die answeres arbeiten nicht wirklich oder andere Probleme hatten, ....Vergleichen NSDate für heute oder gestern

hier Wie auch immer ist, was ich habe „Arbeits ":

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]; 
} 

Nun zum Problem (e):

das ist eine awefull Menge Code für nur ein Datum comparinson zu sein scheint, ist es ein einfacher Weg?

Und die wichtigste Frage ist die Freigabe aller Objekte. Wie ich vermutet habe, verwende ich dies in einem UITableViewController. Ich habe auch diese Zeilen in meinem Code:

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

Das Problem ist, dass so schnell, dass ich Kommentar- eine dieser Linien, meine App stürzt ab und ich habe keine Ahnung, warum?! Ich hoffe, dass mich jemand hier aufklären kann.

Vielen Dank.

+1

Nun, das letzte Bit ist einfach: Sie besitze keine dieser Objekte, also dürfen sie nicht von dir freigegeben werden. Comps ist das einzige Objekt, das Sie zuweisen. Die anderen werden alle entweder als Autoreleased zurückgegeben oder sollen überhaupt nicht veröffentlicht werden. – walkytalky

+0

Danke, gute Beschreibung;) – elementsense

Antwort

12

Der einfachste Weg, es zu tun ist, um nur die description der Daten zu vergleichen:

// 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; 
} 

Wenn Sie das Format der Datumszeichenfolge ändern möchten Sie descriptionWithLocale: stattdessen verwenden könnte.

+15

Verlassen Sie sich nicht auf das Ergebnis der Beschreibungsmethode. Es existiert hauptsächlich zu Debuggingzwecken und ist nicht garantiert dauerhaft oder reversibel. Wenn Sie diesen Stringvergleich verwenden möchten, verwenden Sie einen expliziten NSDateFormatter, um die genaue Zeichenfolge zu generieren, die Sie möchten. Aber das ist ein bisschen Overkill, wenn Sie stattdessen die von NSCalendar erzeugten Komponenten vergleichen können. –

+0

Das Ergebnis der Beschreibungsmethode (in iOS 7.1) liefert das Datum in GMT, was bedeutet, dass es durch den Offset der Zeitzone des aktuellen Benutzers von GMT ausgeschaltet wird. Für mich bedeutet das heute 6 Stunden früher. – dwsolberg

-1

Sie können zwei NSDate-Objekte mit der isEqualToDate-Methode vergleichen, geben ein Bool (ja oder nein) zurück, das Ihnen sagt, ob die Daten gleich sind. Siehe Apple Documentation.

Wie beim Freigeben der Objekte - die Regel in objective-c ist, dass Sie nur Objekte freigeben, denen Sie im Laufe Ihrer Methode Speicher zugewiesen haben. Das einzige Objekt, dem Sie Speicher in Ihrem Code speziell zuweisen, ist comps, also ist es das einzige, das Sie freigeben sollten - und Sie haben es getan. Das Freigeben von Speicher für Objekte, die Sie nie zugewiesen haben, führt wahrscheinlich zum Absturz Ihrer App. Wenn die Methoden, die diese Objekte tatsächlich zugewiesen haben, versuchen, sie zu veröffentlichen, oder sie versuchen, auf sie zuzugreifen, werden sie einen EXC_BAD_ACCESS-Fehler auslösen, da Sie sie bereits freigegeben haben!

So kommentieren Sie nicht einfach diese Freigabelisten, löschen Sie sie aus Ihrem Skript - es gibt keine Notwendigkeit für sie!

+1

'isEqualToDate:' wird hier nicht funktionieren. Es gibt nur das "JA" zurück, wenn die Daten "exakt" gleich sind: "Diese Methode erkennt Untersekundendifferenzen zwischen Daten." (Aus der Klassenreferenz.) – mohsenr

6

Ich weiß, das ist eine alte Frage, aber ich habe gerade etwas Ähnliches selbst gemacht und bin darauf gekommen.

Vor allem seit iOS 4.0 (und Mac OS 10.6) können NSDateFormatter relative Daten tun, was Sie "Heute" und "Yesterday" automatisch gibt.

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

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

Welche Ausgänge:

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

jedoch das OP wurde die Frage, wie ein NSDate für heute oder gestern zu vergleichen, was ich wollte auch beiseite, relative Datumsformatierung tun.Hier ist, was ich kam mit, implementiert als eine Kategorie auf 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 

Der Grund, warum ich wollte, dies zu tun, so ist, dass ich die Zeit der Dinge geschaffen heute zeigen konnte, und das Datum der Dinge heute nicht geschaffen - Ähnlich wie Mail.app die Daten von Nachrichten anzeigt. Es sieht wie folgt aus:

- (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

Ich kann empfehlen, dieses Open-Source-Projekt zu verwenden: https://github.com/erica/NSDate-Extensions

Sie können die aktuellen Methoden überprüfen:

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

Das ist eine großartige Erweiterung - danke Kriv. CocoaPod unterstützt auch: pod 'NSDate-Extensions', '~> 0.0.1' – Fraser

Verwandte Themen