precios libro electrónico electronico electronic ebooks ebook definicion books ios objective-c cocoa-touch nsdate nscalendar

ios - libro - ¿Cómo determinar si un NSDate es hoy?



libro electronico (20)

¡En macOS 10.9+ e iOS 8+, hay un método en NSCalendar / Calendar que hace exactamente esto!

- (BOOL)isDateInToday:(NSDate *)date

Entonces simplemente harías

C objetivo:

BOOL today = [[NSCalendar currentCalendar] isDateInToday:date];

Swift 3:

let today = Calendar.current.isDateInToday(date)

¿Cómo verificar si un NSDate pertenece a hoy?

Solía ​​verificarlo usando los primeros 10 caracteres de [aDate description] . [[aDate description] substringToIndex:10] devuelve una cadena como "YYYY-MM-DD" así que [[[NSDate date] description] substringToIndex:10] la cadena con la cadena devuelta por [[[NSDate date] description] substringToIndex:10] .

¿Hay alguna manera más rápida y / o ordenada de verificar?

Gracias.


¡Hay una manera más fácil que muchas de las respuestas anteriores!

NSDate *date = ... // The date you wish to test NSCalendar *calendar = [NSCalendar currentCalendar]; if([calendar isDateInToday:date]) { //do stuff }


Aquí está mi respuesta de 2 centavos basada en la respuesta aceptada, pero también apoya la API más nueva. Nota: uso el calendario gregoriano ya que la mayoría de las marcas de tiempo son GMT, pero cambia las tuyas como mejor te parezca

func isDateToday(date: NSDate) -> Bool { let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! if calendar.respondsToSelector("isDateInToday:") { return calendar.isDateInToday(date) } let dateComponents = NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay let today = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: NSDate()))! let dateToCompare = calendar.dateFromComponents(calendar.components(dateComponents, fromDate: date))! return dateToCompare == today }


Consulte la entrada de documentación de Apple titulada "Realizar cálculos de calendario" [link] .

El Listado 13 en esa página sugiere que para determinar el número de noches entre días, usa:

- (NSInteger)midnightsFromDate:(NSDate *)startDate toDate:(NSDate *)endDate { NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar]; NSInteger startDay = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:startDate]; NSInteger endDay = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate:endDate]; return endDay - startDay; }

A continuación, puede determinar si dos días son iguales al usar ese método y ver si devuelve 0 o no.



Esto es una derivación de su pregunta, pero si desea imprimir un NSDate con "Hoy" o "Ayer", use la función

- (void)setDoesRelativeDateFormatting:(BOOL)b

para NSDateFormatter


Esto probablemente podría volver a trabajarse como una categoría NSDate, pero utilicé:

// Seconds per day (24h * 60m * 60s) #define kSecondsPerDay 86400.0f + (BOOL) dateIsToday:(NSDate*)dateToCheck { // Split today into components NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents* comps = [gregorian components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit) fromDate:[NSDate date]]; // Set to this morning 00:00:00 [comps setHour:0]; [comps setMinute:0]; [comps setSecond:0]; NSDate* theMidnightHour = [gregorian dateFromComponents:comps]; [gregorian release]; // Get time difference (in seconds) between date and then NSTimeInterval diff = [dateToCheck timeIntervalSinceDate:theMidnightHour]; return ( diff>=0.0f && diff<kSecondsPerDay ); }

(Sin embargo, comparar las dos cadenas de fechas como en la pregunta original casi parece "más limpio" ...)


Intentaría normalizar la fecha de hoy a la medianoche y la segunda fecha, normalizar a la medianoche y comparar si es el mismo NSDate.

De un ejemplo de Apple , así es cómo se normaliza hasta la medianoche de la fecha de hoy, haga lo mismo para la segunda fecha y compare:

NSCalendar * gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents * components = [gregorian components: (NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:[NSDate date]]; NSDate * today = [gregorian dateFromComponents:components];


La solución correcta y segura sin necesidad de desempapetar, trabajando en Swift 2.2 y antes de iOS 8:

func isToday() -> Bool { let calendar = NSCalendar.currentCalendar() if #available(iOS 8.0, *) { return calendar.isDateInToday(self) } let todayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:NSDate()) let dayComponents = calendar.components([.Era, .Year, .Month, .Day], fromDate:self) guard let today = calendar.dateFromComponents(todayComponents), day = calendar.dateFromComponents(dayComponents) else { return false } return today.compare(day) == .OrderedSame }


Mi solución es calcular cuántos días pasaron desde 1970 por división y comparar la parte entera

#define kOneDay (60*60*24) - (BOOL)isToday { NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT]; NSInteger days =[self timeIntervalSince1970] + offset; NSInteger currentDays = [[NSDate date] timeIntervalSince1970] + offset; return (days / kOneDay == currentDays / kOneDay); }


No es necesario hacer malabares con los componentes, las eras y esas cosas.

NSCalendar proporciona un método para obtener el comienzo de una determinada unidad de tiempo para una fecha existente.

Este código tendrá el comienzo de hoy y otra fecha y comparar eso. Si se evalúa como NSOrderedSame , ambas fechas son durante el mismo día, así que hoy.

NSDate *today = nil; NSDate *beginningOfOtherDate = nil; NSDate *now = [NSDate date]; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&today interval:NULL forDate:now]; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfOtherDate interval:NULL forDate:beginningOfOtherDate]; if([today compare:beginningOfOtherDate] == NSOrderedSame) { //otherDate is a date in the current day }


Puede comparar componentes de fecha:

NSDateComponents *otherDay = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:aDate]; NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]]; if([today day] == [otherDay day] && [today month] == [otherDay month] && [today year] == [otherDay year] && [today era] == [otherDay era]) { //do stuff }

Editar:

Me gusta más el método de Stefan, creo que hace una declaración más clara y comprensible si:

NSCalendar *cal = [NSCalendar currentCalendar]; NSDateComponents *components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:[NSDate date]]; NSDate *today = [cal dateFromComponents:components]; components = [cal components:(NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:aDate]; NSDate *otherDate = [cal dateFromComponents:components]; if([today isEqualToDate:otherDate]) { //do stuff }

Chris, he incorporado tu sugerencia. Tuve que buscar qué era era, así que para cualquier otra persona que no sepa, distingue entre BC y AD. Esto probablemente sea innecesario para la mayoría de las personas, pero es fácil de verificar y agrega cierta certeza, así que lo he incluido. Si busca velocidad, probablemente este no sea un buen método.

NOTE que con muchas respuestas en SO, después de 7 años esto está totalmente desactualizado. En Swift ahora solo use .isDateInToday


Si tiene muchas de estas comparaciones de fechas, entonces las llamadas a calendar:components:fromDate comienzan a tomar mucho tiempo. De acuerdo con algunos perfiles que he hecho, parecen ser bastante caros.

Digamos que está intentando determinar cuál de una serie de fechas, digamos NSArray *datesToCompare , es el mismo día que un día determinado, digamos NSDate *baseDate , luego puede usar algo como lo siguiente (parcialmente adaptado de una respuesta anterior):

NSDate *baseDate = [NSDate date]; NSArray *datesToCompare = [NSArray arrayWithObjects:[NSDate date], [NSDate dateWithTimeIntervalSinceNow:100], [NSDate dateWithTimeIntervalSinceNow:1000], [NSDate dateWithTimeIntervalSinceNow:-10000], [NSDate dateWithTimeIntervalSinceNow:100000], [NSDate dateWithTimeIntervalSinceNow:1000000], [NSDate dateWithTimeIntervalSinceNow:50], nil]; // determine the NSDate for midnight of the base date: NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComponents* comps = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:baseDate]; NSDate* theMidnightHour = [calendar dateFromComponents:comps]; // set up a localized date formatter so we can see the answers are right! NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; // determine which dates in an array are on the same day as the base date: for (NSDate *date in datesToCompare) { NSTimeInterval interval = [date timeIntervalSinceDate:theMidnightHour]; if (interval >= 0 && interval < 60*60*24) { NSLog(@"%@ is on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]); } else { NSLog(@"%@ is NOT on the same day as %@", [dateFormatter stringFromDate:date], [dateFormatter stringFromDate:baseDate]); } }

Salida:

Nov 23, 2011 1:32:00 PM is on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 1:33:40 PM is on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 1:48:40 PM is on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 10:45:20 AM is on the same day as Nov 23, 2011 1:32:00 PM Nov 24, 2011 5:18:40 PM is NOT on the same day as Nov 23, 2011 1:32:00 PM Dec 5, 2011 3:18:40 AM is NOT on the same day as Nov 23, 2011 1:32:00 PM Nov 23, 2011 1:32:50 PM is on the same day as Nov 23, 2011 1:32:00 PM


Swift Extension basado en las mejores respuestas:

extension NSDate { func isToday() -> Bool { let cal = NSCalendar.currentCalendar() if cal.respondsToSelector("isDateInToday:") { return cal.isDateInToday(self) } var components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:NSDate()) let today = cal.dateFromComponents(components)! components = cal.components((.CalendarUnitEra | .CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay), fromDate:self); let otherDate = cal.dateFromComponents(components)! return today.isEqualToDate(otherDate) } }


Swift versión de la mejor respuesta:

let cal = NSCalendar.currentCalendar() var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate()) let today = cal.dateFromComponents(components)! components = cal.components([.Era, .Year, .Month, .Day], fromDate:aDate); let otherDate = cal.dateFromComponents(components)! if(today.isEqualToDate(otherDate)) { //do stuff }


También puede verificar el intervalo de tiempo entre la fecha que tiene y la fecha actual:

[myDate timeIntervalSinceNow]

Esto le dará el intervalo de tiempo, en segundos, entre myDate y la fecha / hora actual.

Link .

Editar: Nota para todos: soy consciente de que [myDate timeIntervalSinceNow] no determina inequívocamente si myDate es hoy.

Dejo esta respuesta tal como está, de modo que si alguien está buscando algo similar y [myDate timeIntervalSinceNow] es útil, pueden encontrarla aquí.


Working Swift 3 y 4 extensión de la sugerencia por Catfish_Man:

extension Date { func isToday() -> Bool { return Calendar.current.isDateInToday(self) } }


para iOS7 y versiones anteriores:

//this is now => need that for the current date NSDate * now = [NSDate date]; NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [calendar setTimeZone:[NSTimeZone systemTimeZone]]; NSDateComponents * components = [calendar components:( NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate: now]; [components setMinute:0]; [components setHour:0]; [components setSecond:0]; //this is Today''s Midnight NSDate *todaysMidnight = [calendar dateFromComponents: components]; //now timeIntervals since Midnight => in seconds NSTimeInterval todayTimeInterval = [now timeIntervalSinceDate: todaysMidnight]; //now timeIntervals since OtherDate => in seconds NSTimeInterval otherDateTimeInterval = [now timeIntervalSinceDate: otherDate]; if(otherDateTimeInterval > todayTimeInterval) //otherDate is not in today { if((otherDateTimeInterval - todayTimeInterval) <= 86400) //86400 == a day total seconds { @"yesterday"; } else { @"earlier"; } } else { @"today"; } now = nil; calendar = nil; components = nil; todaysMidnight = nil; NSLog("Thank you :-)");


NSDate *dateOne = yourDate; NSDate *dateTwo = [NSDate date]; switch ([dateOne compare:dateTwo]) { case NSOrderedAscending: NSLog(@”NSOrderedAscending”); break; case NSOrderedSame: NSLog(@”NSOrderedSame”); break; case NSOrderedDescending: NSLog(@”NSOrderedDescending”); break; }


extension NSDate { func isToday() -> Bool { let cal = NSCalendar.currentCalendar() var components = cal.components([.Era, .Year, .Month, .Day], fromDate:NSDate()) let today = cal.dateFromComponents(components)! components = cal.components([.Era, .Year, .Month, .Day], fromDate:self) let otherDate = cal.dateFromComponents(components)! return today.isEqualToDate(otherDate) }

Trabajó para mí en Swift 2.0