iOS: porównaj dwie daty

96

Mam, NSDatektóre muszę porównać z dwoma innymi NSDatei próbuję z NSOrderAscendingi NSOrderDescendingale czy moja data jest równa w pozostałych dwóch terminach?

Przykład: jeśli mam myDate = 24/05/2011 i dwa pozostałe, czyli jeden = 24/05/2011i dwa, 24/05/2011czego mogę użyć?

jazda na rowerze jest lepsza
źródło
1
Nie do końca rozumiem Twoje pytanie, co próbujesz osiągnąć?
arclight
data pierwsza i data druga mogą wynosić jeden = 15/05/2011 i dwa = 31/05/2011, ale muszą być również tego samego dnia jeden = 24/05/2011 i dwa = 24/05/2011, muszę sprawdzić, czy myData jest między datą pierwszą a drugą
CyclingIsBetter
Po prostu wyodrębnij rok, miesiąc i datę i porównaj je w tej kolejności. Jeśli jest remis, porównaj następne pole.
Himadri Choudhury

Odpowiedzi:

210

Zgodnie z dokumentacją Apple dotyczącąNSDate compare:

Zwraca wartość NSComparisonResult, która wskazuje czasową kolejność odbiorcy i inną podaną datę.

- (NSComparisonResult)compare:(NSDate *)anotherDate

Parametry anotherDate

Data, z którą należy porównać odbiorcę. Ta wartość nie może być zerowa. Jeśli wartość wynosi zero, zachowanie jest niezdefiniowane i może ulec zmianie w przyszłych wersjach systemu Mac OS X.

Wartość zwracana

Jeśli:

Odbiornik i innyData są dokładnie sobie równe, NSOrderedSame

Odbiorca jest późniejszy niż inny Data, NSOrderedDescending

Odbiorca jest wcześniej niż inny Data, NSOrderedAscending

Innymi słowy:

if ([date1 compare:date2] == NSOrderedSame) ...

Zauważ, że w twoim konkretnym przypadku może być łatwiejsze przeczytanie i napisanie tego:

if ([date2 isEqualToDate:date2]) ...

Zobacz dokumentację Apple dotyczącą tego .

Vincent Guerci
źródło
ale f ([date1 porównaj: date2] == NSOrderedSame) sprawdź także godzinę, minutę i sekundy i nie chcę tego
CyclingIsBetter
1
Twoje pytanie było trochę niejasne, przepraszam, spójrz na stackoverflow.com/questions/1889164/3092009#3092009 , znajdziesz odpowiedź na to pytanie.
Vincent Guerci
Ta odpowiedź jest poprawna w obu przypadkach. Aby kontrolować komponenty daty, które porównujesz, użyj NSDateComponents
Nazira
32

Po częstym przeszukiwaniu stackoverflow i internetu, doszedłem do wniosku, że najlepszym sposobem na zrobienie tego jest tak:

- (BOOL)isEndDateIsSmallerThanCurrent:(NSDate *)checkEndDate
{
    NSDate* enddate = checkEndDate;
    NSDate* currentdate = [NSDate date];
    NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
    double secondsInMinute = 60;
    NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;

    if (secondsBetweenDates == 0)
        return YES;
    else if (secondsBetweenDates < 0)
        return YES;
    else
        return NO;
}

Możesz również zmienić to na różnicę między godzinami.

Cieszyć się!


Edytuj 1

Jeśli chcesz porównać tylko datę z formatem dd / MM / rrrr, musisz dodać poniższe linie między NSDate* currentdate = [NSDate date];&&NSTimeInterval distance

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"dd/MM/yyyy"];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]
                          autorelease]];

NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];

currentdate = [dateFormatter dateFromString:stringDate];
Yossi Tsafar
źródło
1
Dzięki temu działa lepiej niż porównanie lub
jestEqualToDate
Zgoda. Znalazłem problemy przy użyciu funkcji porównania i isEqualToDate. Jasne, mogą to być dodatkowe 2 wiersze kodu, ale jest bardziej niezawodny.
Trener Roebuck
23

Rozumiem, że pytasz, jaka jest wartość zwracana w funkcji porównania.

Jeśli daty są równe, to powrót NSOrderedSame

Jeśli rosnąco (2. arg> 1. arg) powróć NSOrderedAscending

Jeśli malejąco (2. arg <1. arg) powróć NSOrderedDescending

Himadri Choudhury
źródło
Dobry sposób na myślenie o wchodzeniu i schodzeniu.
David
16

Nie wiem dokładnie, czy o to pytałeś, ale jeśli chcesz porównać tylko składnik daty w NSDate, musisz użyć NSCalendar i NSDateComponents, aby usunąć składnik czasu.

Coś takiego powinno działać jako kategoria dla NSDate:

- (NSComparisonResult)compareDateOnly:(NSDate *)otherDate {
    NSUInteger dateFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit;
    NSCalendar *gregorianCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    NSDateComponents *selfComponents = [gregorianCalendar components:dateFlags fromDate:self];
    NSDate *selfDateOnly = [gregorianCalendar dateFromComponents:selfComponents];

    NSDateComponents *otherCompents = [gregorianCalendar components:dateFlags fromDate:otherDate];
    NSDate *otherDateOnly = [gregorianCalendar dateFromComponents:otherCompents];
    return [selfDateOnly compare:otherDateOnly];
}
Matthias Bauch
źródło
2

NSDatefaktycznie reprezentuje przedział czasu w sekundach od daty odniesienia (myślę, że 1 stycznia 2000 UTC). Wewnętrznie używana jest liczba zmiennoprzecinkowa podwójnej precyzji, więc jest bardzo mało prawdopodobne, aby dwie dowolne daty były równe, nawet jeśli są tego samego dnia. Jeśli chcesz sprawdzić, czy konkretna data przypada w określony dzień, prawdopodobnie musisz użyć NSDateComponents. na przykład

NSDateComponents* dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2011];
[dateComponents setMonth: 5];
[dateComponents setDay: 24];
/*
 *  Construct two dates that bracket the day you are checking.  
 *  Use the user's current calendar.  I think this takes care of things like daylight saving time.
 */
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* startOfDate = [calendar dateFromComponents: dateComponents];
NSDateComponents* oneDay = [[NSDateComponents alloc] init];
[oneDay setDay: 1];
NSDate* endOfDate = [calendar dateByAddingComponents: oneDay toDate: startOfDate options: 0];
/*
 *  Compare the date with the start of the day and the end of the day.
 */
NSComparisonResult startCompare = [startOfDate compare: myDate];
NSComparisonResult endCompare = [endOfDate compare: myDate];

if (startCompare != NSOrderedDescending && endCompare == NSOrderedDescending)
{
    // we are on the right date
} 
JeremyP
źródło
2

Sprawdź następującą funkcję dla porównania dat, najpierw utwórz dwa obiekty NSDate i przekaż do funkcji: Dodaj poniższe wiersze kodu w viewDidload lub zgodnie ze swoim scenariuszem.

-(void)testDateComaparFunc{

NSString *getTokon_Time1 = @"2016-05-31 03:19:05 +0000";
NSString *getTokon_Time2 = @"2016-05-31 03:18:05 +0000";
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss Z"];
NSDate *tokonExpireDate1=[dateFormatter dateFromString:getTokon_Time1];
NSDate *tokonExpireDate2=[dateFormatter dateFromString:getTokon_Time2];
BOOL isTokonValid = [self dateComparision:tokonExpireDate1 andDate2:tokonExpireDate2];}

tutaj jest funkcja

-(BOOL)dateComparision:(NSDate*)date1 andDate2:(NSDate*)date2{

BOOL isTokonValid;

if ([date1 compare:date2] == NSOrderedDescending) {
    //"date1 is later than date2
    isTokonValid = YES;
} else if ([date1 compare:date2] == NSOrderedAscending) {
    //date1 is earlier than date2
    isTokonValid = NO;
} else {
   //dates are the same
    isTokonValid = NO;

}

return isTokonValid;}

Po prostu zmień datę i przetestuj powyższą funkcję :)

Akhtar
źródło