iOS: compara dos fechas

96

Tengo una NSDateque debo comparar con otras dos NSDatee intento con NSOrderAscendingy NSOrderDescendingpero ¿si mi fecha es igual en otras dos fechas?

Ejemplo: si tengo un myDate = 24/05/2011 y otros dos que son uno = 24/05/2011y dos, 24/05/2011¿qué puedo usar?

CiclismoEsMejor
fuente
1
No entiendo completamente tu pregunta, ¿qué estás tratando de lograr?
arclight
la fecha uno y la fecha dos pueden ser una = 15/05/2011 y dos = 31/05/2011 pero también deben ser el mismo día uno = 24/05/2011 y dos = 24/05/2011, entonces debo verificar si myData está entre la fecha uno y la fecha dos
cyclingIsBetter
Simplemente extraiga el año, el mes y la fecha y compárelos en ese orden. Si hay un empate, compare el siguiente campo.
Himadri Choudhury

Respuestas:

210

Según la documentación de Apple deNSDate compare:

Devuelve un valor NSComparisonResult que indica el orden temporal del receptor y otra fecha determinada.

- (NSComparisonResult)compare:(NSDate *)anotherDate

Parámetros anotherDate

La fecha con la que comparar al receptor. Este valor no debe ser nulo. Si el valor es nulo, el comportamiento no está definido y puede cambiar en futuras versiones de Mac OS X.

Valor devuelto

Si:

El receptor y otra fecha son exactamente iguales entre sí, NSOrderedSame

El receptor es posterior en el tiempo a otra fecha, NSOrderedDescending

El receptor es anterior en el tiempo a otra fecha, NSOrderedAscending

En otras palabras:

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

Tenga en cuenta que podría ser más fácil en su caso particular leer y escribir esto:

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

Consulte la documentación de Apple sobre este .

Vincent Guerci
fuente
pero f ([date1 compare: date2] == NSOrderedSame) verifique también la hora, los minutos y los segundos y no los quiero
cyclingIsBetter
1
Su pregunta fue un poco confusa, lo siento, eche un vistazo a stackoverflow.com/questions/1889164/3092009#3092009 , encontrará la respuesta a esto.
Vincent Guerci
Esta respuesta es correcta en ambos sentidos. Para controlar los componentes de fecha que está comparando, useNSDateComponents
Nazir
32

Después de buscar mucho en stackoverflow y en la web, tengo que concluir que la mejor manera de hacerlo es así:

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

También puede cambiarlo a diferencia entre horas.

¡Disfrutar!


Editar 1

Si desea comparar la fecha con el formato de dd / MM / aaaa solamente, debe agregar las siguientes líneas entre 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
fuente
1
Gracias, esto funciona mejor que comparar o isEqualToDate
ArdenDev
Convenido. He encontrado problemas al utilizar compare & isEqualToDate. Claro, pueden ser 2 líneas adicionales de código, pero es más confiable.
Entrenador Roebuck
23

Supongo que está preguntando cuál es el valor de retorno en la función de comparación.

Si las fechas son iguales entonces regresando NSOrderedSame

Si es ascendente (2do argumento> 1er argumento) regresa NSOrderedAscending

Si es descendente (2nd arg <1st arg) return NSOrderedDescending

Himadri Choudhury
fuente
Buena forma de pensar en ascender y descender.
David
16

No sé exactamente si ha preguntado esto, pero si solo desea comparar el componente de fecha de un NSDate, debe usar NSCalendar y NSDateComponents para eliminar el componente de tiempo.

Algo como esto debería funcionar como una categoría para 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
fuente
2

NSDateen realidad representa un intervalo de tiempo en segundos desde una fecha de referencia (creo que el 1 de enero de 2000 UTC). Internamente, se usa un número de punto flotante de doble precisión, por lo que es muy poco probable que dos fechas arbitrarias se comparen de la misma manera, incluso si son el mismo día. Si desea ver si una fecha en particular cae en un día en particular, probablemente necesite usar NSDateComponents. p.ej

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
fuente
2

Verifique la siguiente función para la comparación de fechas, primero cree dos objetos NSDate y pase a la función: Agregue las siguientes líneas de código en viewDidload o según su escenario.

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

aquí está la función

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

Simplemente cambie la fecha y pruebe la función anterior :)

Akhtar
fuente