Como comparar dois NSDates: Qual é mais recente?

Eu estou tentando conseguir uma synchronization dropbox e preciso comparar as datas de dois arquivos. Um está na minha conta dropBox e um está no meu iPhone.

Eu vim com o seguinte, mas recebo resultados inesperados. Eu acho que estou fazendo algo fundamentalmente errado ao comparar as duas datas. Eu simplesmente usei os operadores , mas acho que isso não é bom, já que estou comparando duas strings NSDate. Aqui vamos nós:

NSLog(@"dB...lastModified: %@", dbObject.lastModifiedDate); NSLog(@"iP...lastModified: %@", [self getDateOfLocalFile:@"NoteBook.txt"]); if ([dbObject lastModifiedDate] < [self getDateOfLocalFile:@"NoteBook.txt"]) { NSLog(@"...db is more up-to-date. Download in progress..."); [self DBdownload:@"NoteBook.txt"]; NSLog(@"Download complete."); } else { NSLog(@"...iP is more up-to-date. Upload in progress..."); [self DBupload:@"NoteBook.txt"]; NSLog(@"Upload complete."); } 

Isso me deu a seguinte saída (aleatória e errada):

 2011-05-11 14:20:54.413 NotePage[6918:207] dB...lastModified: 2011-05-11 13:18:25 +0000 2011-05-11 14:20:54.414 NotePage[6918:207] iP...lastModified: 2011-05-11 13:20:48 +0000 2011-05-11 14:20:54.415 NotePage[6918:207] ...db is more up-to-date. 

ou este que está correto:

 2011-05-11 14:20:25.097 NotePage[6903:207] dB...lastModified: 2011-05-11 13:18:25 +0000 2011-05-11 14:20:25.098 NotePage[6903:207] iP...lastModified: 2011-05-11 13:19:45 +0000 2011-05-11 14:20:25.099 NotePage[6903:207] ...iP is more up-to-date. 

Vamos supor duas datas:

 NSDate *date1; NSDate *date2; 

Então a seguinte comparação dirá qual é anterior / posterior / mesmo:

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

Por favor, consulte a documentação da class NSDate para mais detalhes.

Tarde para a festa, mas outra maneira fácil de comparar objects NSDate é convertê-los em tipos primitivos que permitem o uso fácil de ‘>’ ‘<' '==' etc.

por exemplo.

 if ([dateA timeIntervalSinceReferenceDate] > [dateB timeIntervalSinceReferenceDate]) { //do stuff } 

timeIntervalSinceReferenceDate converte a data em segundos desde a data de referência (1 de janeiro de 2001, GMT). Como timeIntervalSinceReferenceDate retorna um NSTimeInterval (que é um double typedef), podemos usar comparadores primitivos.

No Swift, você pode sobrecarregar os operadores existentes:

 func > (lhs: NSDate, rhs: NSDate) -> Bool { return lhs.timeIntervalSinceReferenceDate > rhs.timeIntervalSinceReferenceDate } func < (lhs: NSDate, rhs: NSDate) -> Bool { return lhs.timeIntervalSinceReferenceDate < rhs.timeIntervalSinceReferenceDate } 

Então, você pode comparar NSDates diretamente com < , > e == (já suportado).

NSDate tem uma function de comparação.

compare: Retorna um valor NSComparisonResult que indica a ordenação temporal do receptor e outra data determinada.

 (NSComparisonResult)compare:(NSDate *)anotherDate 

parameters : anotherDate A data na qual comparar o receptor. Este valor não deve ser nulo. Se o valor for nulo, o comportamento é indefinido e pode mudar em versões futuras do Mac OS X.

Valor de retorno:

  • Se o destinatário e o anotherDate forem exatamente iguais entre si, NSOrderedSame
  • Se o receptor estiver mais atrasado do que anotherDate, NSOrderedDescending
  • Se o receptor estiver adiantado em relação a anotherDate, NSOrderedAscending .

Você deseja usar os methods de comparação NSDate :, laterDate :, earlyDate: ou isEqualToDate:. Usar os operadores nessa situação é comparar os pointers, não as datas

 - (NSDate *)earlierDate:(NSDate *)anotherDate 

Isso retorna o anterior do receptor e anotherDate. Se ambos forem iguais, o destinatário será retornado.

Alguns utilitários de data, incluindo comparações em inglês, o que é legal:

 #import  @interface NSDate (Util) -(BOOL) isLaterThanOrEqualTo:(NSDate*)date; -(BOOL) isEarlierThanOrEqualTo:(NSDate*)date; -(BOOL) isLaterThan:(NSDate*)date; -(BOOL) isEarlierThan:(NSDate*)date; - (NSDate*) dateByAddingDays:(int)days; @end 

A implementação:

 #import "NSDate+Util.h" @implementation NSDate (Util) -(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); } - (NSDate *) dateByAddingDays:(int)days { NSDate *retVal; NSDateComponents *components = [[NSDateComponents alloc] init]; [components setDay:days]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; retVal = [gregorian dateByAddingComponents:components toDate:self options:0]; return retVal; } @end 

Você deveria usar :

 - (NSComparisonResult)compare:(NSDate *)anotherDate 

para comparar datas. Não há sobrecarga do operador no objective C.

Eu encontrei quase a mesma situação, mas no meu caso eu estou verificando se a diferença de número de dias

 NSCalendar *cal = [NSCalendar currentCalendar]; NSDateComponents *compDate = [cal components:NSDayCalendarUnit fromDate:fDate toDate:tDate options:0]; int numbersOfDaysDiff = [compDate day]+1; // do what ever comparison logic with this int. 

Útil quando você precisa comparar NSDate em dias / mês / ano

Por que vocês não usam esses methods de comparação NSDate :

 - (NSDate *)earlierDate:(NSDate *)anotherDate; - (NSDate *)laterDate:(NSDate *)anotherDate; 

Você pode comparar duas datas por este método também

  switch ([currenttimestr compare:endtimestr]) { case NSOrderedAscending: // dateOne is earlier in time than dateTwo break; case NSOrderedSame: // The dates are the same break; case NSOrderedDescending: // dateOne is later in time than dateTwo break; } 

Eu tentei isso espero que funcione para você

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; int unitFlags =NSDayCalendarUnit; NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; NSDate *myDate; //= [[NSDate alloc] init]; [dateFormatter setDateFormat:@"dd-MM-yyyy"]; myDate = [dateFormatter dateFromString:self.strPrevioisDate]; NSDateComponents *comps = [gregorian components:unitFlags fromDate:myDate toDate:[NSDate date] options:0]; NSInteger day=[comps day]; 

Use esta function simples para comparação de datas

 -(BOOL)dateComparision:(NSDate*)date1 andDate2:(NSDate*)date2{ BOOL isTokonValid; if ([date1 compare:date2] == NSOrderedDescending) { NSLog(@"date1 is later than date2"); isTokonValid = YES; } else if ([date1 compare:date2] == NSOrderedAscending) { NSLog(@"date1 is earlier than date2"); isTokonValid = NO; } else { isTokonValid = NO; NSLog(@"dates are the same"); } return isTokonValid;}