iOS: сравните две даты

96

У меня есть , NSDateчто я должен сравнить с двумя другими , NSDateи я стараюсь с NSOrderAscendingи , NSOrderDescendingно если моя дата ровно в двух других дат?

Пример: если у меня есть a myDate = 24/05/2011 и два других, которые равны one = 24/05/2011и two, 24/05/2011что я могу использовать?

ВелоспортIsBetter
источник
1
Я не совсем понимаю ваш вопрос, чего вы пытаетесь достичь?
arclight
дата один и дата два могут быть один = 15.05.2011 и два = 31.05.2011, но они также должны быть в один и тот же день: один = 24.05.2011 и два = 24.05.2011, тогда я должен проверить, myData находится между датой один и датой два
cyclingIsBetter
Просто извлеките год, месяц и дату и сравните их в указанном порядке. Если есть ничья, сравните следующее поле.
Химадри Чоудхури

Ответы:

210

Согласно документации AppleNSDate compare:

Возвращает значение NSComparisonResult, которое указывает временное упорядочение получателя и другую заданную дату.

- (NSComparisonResult)compare:(NSDate *)anotherDate

Параметры anotherDate

Дата, с которой сравнивается получатель. Это значение не должно быть нулевым. Если значение равно нулю, поведение не определено и может измениться в будущих версиях Mac OS X.

Возвращаемое значение

Если:

Получатель и anotherDate в точности равны друг другу, NSOrderedSame

Получатель позже, чем другой Дата, NSOrderedDescending

Получатель раньше, чем anotherDate, NSOrderedAscending

Другими словами:

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

Обратите внимание, что в вашем конкретном случае может быть проще прочитать и написать это:

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

См. Документацию Apple об этом .

Винсент Гуэрчи
источник
но f ([date1 compare: date2] == NSOrderedSame) проверьте также часы, минуты и секунды, и я не хочу этого
cyclingIsBetter
1
ваш вопрос был немного неясным, извините, посмотрите stackoverflow.com/questions/1889164/3092009#3092009 , вы найдете ответ на это.
Винсент Гуэрчи
Этот ответ верен в обоих отношениях. Для контроля компонентов даты, которые вы сравниваете, используйтеNSDateComponents
Назир
32

После долгих поисков stackoverflow и Интернета я пришел к выводу, что лучший способ сделать это так:

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

Вы также можете изменить это на разницу между часами.

Наслаждайтесь!


Редактировать 1

Если вы хотите сравнить дату только с форматом dd / MM / yyyy, вам нужно добавить строки ниже между 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];
Йоси Цафар
источник
1
Спасибо, это работает лучше, чем сравнивать или isEqualToDate
ArdenDev
Согласовано. Я обнаружил проблемы с использованием compare & isEqualToDate. Конечно, это могут быть лишние 2 строчки кода, но это более надежно.
Тренер Робак
23

Я так понимаю, вы спрашиваете, какое возвращаемое значение имеет функция сравнения.

Если даты совпадают, возвращается NSOrderedSame

Если по возрастанию (2-й аргумент> 1-й аргумент) вернуть NSOrderedAscending

Если по убыванию (2-й аргумент <1-й аргумент) вернуть NSOrderedDescending

Химадри Чоудхури
источник
Хороший способ думать о подъеме и спуске.
Дэвид
16

Я не знаю точно, спрашивали ли вы об этом, но если вы хотите сравнить только компонент даты в NSDate, вы должны использовать NSCalendar и NSDateComponents, чтобы удалить компонент времени.

Что-то вроде этого должно работать как категория для 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];
}
Маттиас Баух
источник
2

NSDateна самом деле представляет собой временной интервал в секундах с даты отсчета (я думаю, 1 января 2000 года по Гринвичу). Внутри используется число с плавающей запятой двойной точности, поэтому маловероятно, что две произвольные даты будут сравниваться как равные, даже если они находятся в один и тот же день. Если вы хотите узнать, приходится ли конкретная дата на конкретный день, вам, вероятно, нужно использовать NSDateComponents. например

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
источник
2

Проверьте следующую функцию для сравнения дат. Сначала создайте два объекта NSDate и перейдите к функции: Добавьте следующие строки кода в viewDidload или в соответствии с вашим сценарием.

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

вот функция

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

Просто измените дату и проверьте функцию выше :)

Ахтар
источник