So vergleichen Sie zwei Daten in Objective-C

70

Ich habe zwei Daten: 2009-05-11und das aktuelle Datum. Ich möchte überprüfen, ob das angegebene Datum das aktuelle Datum ist oder nicht. Wie ist das möglich.

Raju
quelle
Wenn Sie sich die Antworten ansehen, ist nicht klar, ob Sie zwei NSDateInstanzen buchstäblich auf Gleichheit (denselben Zeitpunkt) vergleichen oder wissen möchten, ob sie sich am selben Kalendertag befinden.
Nikolai Ruhe

Antworten:

156

Kakao hat dafür einige Methoden :

in NSDate

isEqualToDate:  
– earlierDate:  
– laterDate:  
– compare:

Wenn Sie verwenden - (NSComparisonResult)compare:(NSDate *)anotherDate, erhalten Sie eines der folgenden zurück:

The receiver and anotherDate are exactly equal to each other, NSOrderedSame
The receiver is later in time than anotherDate, NSOrderedDescending
The receiver is earlier in time than anotherDate, NSOrderedAscending.

Beispiel:

NSDate * now = [NSDate date];
NSDate * mile = [[NSDate alloc] initWithString:@"2001-03-24 10:45:32 +0600"];
NSComparisonResult result = [now compare:mile];

NSLog(@"%@", now);
NSLog(@"%@", mile);

switch (result)
{
    case NSOrderedAscending: NSLog(@"%@ is in future from %@", mile, now); break;
    case NSOrderedDescending: NSLog(@"%@ is in past from %@", mile, now); break;
    case NSOrderedSame: NSLog(@"%@ is the same as %@", mile, now); break;
    default: NSLog(@"erorr dates %@, %@", mile, now); break;
}

[mile release];
stefanB
quelle
1
Wie beantwortet dies die ursprüngliche Frage "ob das angegebene Datum das aktuelle Datum ist oder nicht"? [NSDate date] ist NSOrderedSame zu einem festen Datum, nicht für 24 Stunden, sondern für weniger als eine Sekunde.
Chei
Dies funktioniert nicht für iOS. Siehe akzeptierte Antwort auf: stackoverflow.com/questions/14702626/…
Alexander von Norwegen
@HappyFlow die Frage ist markiert, cocoaes erwähnt nicht iOS, für weitere Informationen versuchen Sie Google "Kakao" vs "Kakao Touch"
stefanB
@stefanB Mein schlechtes, das habe ich nicht gesehen.
Alexander von Norwegen
@AlexanderofNorway Dies funktioniert in der Tat für iOS seit iOS 2.0 gemäß Apple-Dokumenten: developer.apple.com/library/ios/documentation/Cocoa/Reference/… :
Albert Renshaw
44

Hier Kumpel. Diese Funktion passt Ihr Datum an ein bestimmtes Datum an und kann feststellen, ob sie übereinstimmen oder nicht. Sie können die Komponenten auch an Ihre Anforderungen anpassen.

- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {
NSCalendar* calendar = [NSCalendar currentCalendar];

unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];

return [comp1 day]   == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year]  == [comp2 year];}

Grüße, Naveed Butt

Naveed Rafi
quelle
3
Dies ist die richtige Antwort. Die Top-Antwort ist zwar allgemeiner, bietet jedoch eine spezifische Lösung für das vorgestellte Problem.
Elsurudo
2
EINFACH PERFEKT!! WURDE VERSCHIEDENE METHODEN VERSUCHT, DIE HANDY KOMMEN
Raghul
2
@Naveed Rafi Dies ist die genaueste und nützlichste Antwort, die ich auf StackOverflow in den 2 Jahren gesehen habe, in denen ich seine Dienste genieße.
Simon
40
NSDate *today = [NSDate date]; // it will give you current date
NSDate *newDate = [NSDate dateWithString:@"xxxxxx"]; // your date 

NSComparisonResult result; 
//has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending

result = [today compare:newDate]; // comparing two dates

if(result==NSOrderedAscending)
    NSLog(@"today is less");
else if(result==NSOrderedDescending)
    NSLog(@"newDate is less");
else
    NSLog(@"Both dates are same");

Es gibt andere Möglichkeiten, wie Sie NSDate-Objekte vergleichen können. Jede der Methoden ist bei bestimmten Aufgaben effizienter. Ich habe die Vergleichsmethode gewählt, da sie die meisten Ihrer grundlegenden Datumsvergleichsanforderungen erfüllt.

Sajjad
quelle
32

Diese Kategorie bietet eine gute Möglichkeit, NSDates zu vergleichen:

#import <Foundation/Foundation.h>

@interface NSDate (Compare)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date;
-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date;
-(BOOL) isLaterThan:(NSDate*)date;
-(BOOL) isEarlierThan:(NSDate*)date;
//- (BOOL)isEqualToDate:(NSDate *)date; already part of the NSDate API

@end

Und die Umsetzung:

#import "NSDate+Compare.h"

@implementation NSDate (Compare)

-(BOOL) isLaterThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedAscending);
}

-(BOOL) isEarlierThanOrEqualTo:(NSDate*)date {
    return !([self compare:date] == NSOrderedDescending);
}
-(BOOL) isLaterThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedDescending);

}
-(BOOL) isEarlierThan:(NSDate*)date {
    return ([self compare:date] == NSOrderedAscending);
}

@end

Einfach zu benutzen:

if([aDateYouWantToCompare isEarlierThanOrEqualTo:[NSDate date]]) // [NSDate date] is now
{
    // do your thing ...
}
Pascal
quelle
1
Dankeschön! Dies ist viel besser, als Code mit den für Daten unverständlichen NSComparisonResults direkt darin zu haben.
Dan Rosenstark
1
Apple sollte in Betracht ziehen, dies zu implementieren. Weitaus einfacher als das Erstellen von switch-Anweisungen für früher als oder gleich und später als oder gleich.
Geekinit
23

Wenn Sie beide Termine machen NSDates Sie verwenden können NSDate‚s - compare:Methode:

NSComparisonResult result = [Date2 compare:Date1];

if(result==NSOrderedAscending)
    NSLog(@"Date1 is in the future");
else if(result==NSOrderedDescending)
    NSLog(@"Date1 is in the past");
else
    NSLog(@"Both dates are the same");

Sie können an der Dokumentation einen Blick hier .

Alex Rozanski
quelle
15

Mit dieser Methode können Sie auch zwei Daten vergleichen

NSDate * dateOne = [NSDate date];
NSDate * dateTwo = [NSDate date];

if([dateOne compare:dateTwo] == NSOrderedAscending)
{

}
kapil
quelle
2
Interessante Konstanten mit aller Macht zu vergleichen sein: NSOrderedAscending, NSOrderedSameund NSOrderedDescending, aber die OP wahrscheinlich will NSOrderedSamefür sein besonderes Problem dar .
Kris
9

Der beste Weg, den ich gefunden habe, war, den Unterschied zwischen dem angegebenen Datum und dem heutigen Tag zu überprüfen:

NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* now = [NSDate date];
int differenceInDays =
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:date] -
[calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:now];

Gemäß Listing 13 der Kalenderberechnungen im Apple- Programmierhandbuch für Datum und Uhrzeit [NSCalendar ordinalityOfUnit: NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate: myDate] erhalten Sie die Anzahl der Mitternächte seit Beginn der Ära. Auf diese Weise können Sie leicht überprüfen, ob das Datum gestern, heute oder morgen ist.

switch (differenceInDays) {
    case -1:
        dayString = @"Yesterday";
        break;
    case 0:
        dayString = @"Today";
        break;
    case 1:
        dayString = @"Tomorrow";
        break;
    default: {
        NSDateFormatter* dayFormatter = [[NSDateFormatter alloc] init];
        [dayFormatter setLocale:usLocale];
        [dayFormatter setDateFormat:@"dd MMM"];
        dayString = [dayFormatter stringFromDate: date];
        break;
    }
}
Chei
quelle
4
NSDateFormatter *df= [[NSDateFormatter alloc] init];

[df setDateFormat:@"yyyy-MM-dd"];

NSDate *dt1 = [[NSDate alloc] init];

NSDate *dt2 = [[NSDate alloc] init];

dt1=[df dateFromString:@"2011-02-25"];

dt2=[df dateFromString:@"2011-03-25"];

NSComparisonResult result = [dt1 compare:dt2];

switch (result)
{

        case NSOrderedAscending: NSLog(@"%@ is greater than %@", dt2, dt1); break;

        case NSOrderedDescending: NSLog(@"%@ is less %@", dt2, dt1); break;

        case NSOrderedSame: NSLog(@"%@ is equal to %@", dt2, dt1); break;

        default: NSLog(@"erorr dates %@, %@", dt2, dt1); break;

}

Viel Spaß beim Codieren ......

iphonedev23
quelle
3

In Cocoa, vergleichen Daten, die Verwendung eines isEqualToDate, compare, laterDate, und earlierDateMethoden auf NSDateObjekte, instanziiert mit den Daten , die Sie benötigen.

Dokumentation:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDate/isEqualToDate:
http://developer.apple. de / documentation / Cocoa / Reference / Foundation / Classes / NSDate_Class / Reference / Reference.html # // apple_ref / occ / instm / NSDate / previousDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ Klassen / NSDate_Class / Reference / Reference.html # // apple_ref / occ / instm / NSDate / laterDate:
http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html# // apple_ref / occ / instm / NSDate / compare:

Suvesh Pratapa
quelle
2

Was Sie wirklich brauchen, ist, zwei Objekte der gleichen Art zu vergleichen.

  1. Erstellen Sie ein NSDate aus Ihrem Zeichenfolgendatum (@ "2009-05-11"):
    http://blog.evandavey.com/2008/12/how-to-convert-a-string-to-nsdate.html

  2. Wenn das aktuelle Datum ebenfalls eine Zeichenfolge ist, machen Sie es zu einem NSDate. Wenn es bereits ein NSDate ist, lassen Sie es.

David Salzer
quelle
3
Sie können nicht zwei Objekte vergleichen, indem Sie ==
oxigen
Mein Fehler, beantwortete gleichzeitig eine andere Frage. Vielen Dank für den Kommentar.
David Salzer
1

Hier ist die Swift-Variante von Pascals Antwort:

extension NSDate {

    func isLaterThanOrEqualTo(date:NSDate) -> Bool {
        return !(self.compare(date) == NSComparisonResult.OrderedAscending)
    }

    func isEarlierThanOrEqualTo(date:NSDate) -> Bool {
        return !(self.compare(date) == NSComparisonResult.OrderedDescending)
    }

    func isLaterThan(date:NSDate) -> Bool {
        return (self.compare(date) == NSComparisonResult.OrderedDescending)
    }

    func isEarlierThan(date:NSDate) -> Bool {
        return (self.compare(date) == NSComparisonResult.OrderedAscending)
    }
}

Welches kann verwendet werden als:

self.expireDate.isEarlierThanOrEqualTo(NSDate())
Antoine
quelle
1

Hier ist die Funktion aus Naveed Rafis Antwort, die in Swift konvertiert wurde, wenn jemand anderes danach sucht:

func isSameDate(#date1: NSDate, date2: NSDate) -> Bool {
    let calendar = NSCalendar()
    let date1comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date1)
    let date2comp = calendar.components(.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit, fromDate: date2)
    return (date1comp.year == date2comp.year) && (date1comp.month == date2comp.month) && (date1comp.day == date2comp.day)
}
stephenspann
quelle
0
Get Today's Date:

NSDate* date = [NSDate date];

Create a Date From Scratch:    
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.year = 2015;
comps.month = 12;
comps.day = 31;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* date = [calendar dateFromComponents:comps];


Add a day to a Date:  
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = 1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* tomorrow = [calendar dateByAddingComponents:comps toDate:date options:nil];


Subtract a day from a Date:    
NSDate* date = [NSDate date];
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.day = -1;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* yesterday = [calendar dateByAddingComponents:comps toDate:date options:nil];



Convert a Date to a String:  

NSDate* date = [NSDate date];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = @"MMMM dd, yyyy";
NSString* dateString = [formatter stringFromDate:date];


Convert a String to a Date:

NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
formatter.dateFormat = @"MMMM dd, yyyy";
NSDate* date = [formatter dateFromString:@"August 02, 2014"];


Find how many days are in a month:    
NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSRange currentRange = [cal rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger numberOfDays = currentRange.length;


Calculate how much time something took:   

NSDate* start = [NSDate date];
for(int i = 0; i < 1000000000; i++);
NSDate* end = [NSDate date];
NSTimeInterval duration = [end timeIntervalSinceDate:start];


Find the Day Of Week for a specific Date:

NSDate* date = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSInteger dow = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];

Verwenden Sie dann NSComparisonResult, um das Datum zu vergleichen.

Avijit Nagare
quelle
-3

..

NSString *date = @"2009-05-11"
NSString *nowDate = [[[NSDate date]description]substringToIndex: 10];
if([date isEqualToString: nowDate])
{
// your code
}
Oxigen
quelle
2
Ich denke, es wäre viel nützlicher, "Datum" in ein NSDate-Objekt umzuwandeln und dann NSDate-Objekte zu vergleichen. Dieser Code wird funktionieren, aber substringToIndex: 10 ist wirklich ein Hack. Wenn Sie weitere Informationen benötigen, z. B. welches Datum aktueller ist, müssen Sie dies auch so tun.
Ben Gotow
Natürlich können Sie NSDate-Objekte vergleichen. NSDate enthält jedoch Informationen zu Datum und Uhrzeit. Ihre Anforderungen 1. Erstellen Sie NSDate aus der Zeichenfolge. 2. Entfernen Sie die Informationen zum aktuellen Datum über die Uhrzeit (setzen Sie die Uhrzeit auf 00:00:00). Vergleichen Sie die Daten erst danach. Ich denke, dass dieser Weg nicht einfach und schnell ist.
Oxigen
Wenn Sie nur am Tag selbst interessiert sind, können Sie NSDates erstellen und dann mit NSCalendar NSDateComponents herausholen. An diesem Punkt können Sie nur die Werte, an denen Sie interessiert sind, numerisch vergleichen. Sie können auch Komponenten für die Anzahl von erhalten Tage seit der Epoche, um in einem einzigen Vergleich zu verwenden.
Jim Dovey
1
Sie sollten nicht vergleichen, indem Sie eine NSDate-Beschreibung mit einem Teilstring versehen, da Apple das Format ändern kann und dies dann nicht mehr funktioniert. Ich sage dies, weil dies der gleiche Grund ist, warum meine App bei einem neuen Betriebssystem-Update abstürzt.