¿Cómo puedo obtener un objeto NSDate para hoy a la medianoche?

¿Cuál es la forma más eficiente de obtener un objeto NSDate que representa la medianoche del día actual?

Prueba esto:

NSDate *const date = NSDate.date; NSCalendar *const calendar = NSCalendar.currentCalendar; NSCalendarUnit const preservedComponents = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay); NSDateComponents *const components = [calendar components:preservedComponents fromDate:date]; NSDate *const normalizedDate = [calendar dateFromComponents:components]; 

Nueva API en iOS 8

iOS 8 incluye un nuevo método en NSCalendar llamado startOfDayForDate , que es realmente fácil de usar:

 let startOfToday = NSCalendar.currentCalendar().startOfDayForDate(NSDate()) 

Descripción de Apple:

Esta API devuelve la fecha del primer momento de una fecha determinada. Pase [NSDate date], por ejemplo, si desea el inicio de “hoy”. Si hubo dos midnights, devuelve el primero. Si no había ninguno, devuelve el primer momento que sí existió.

Actualización, con respecto a las zonas horarias:

Como startOfDayForDate es un método en NSCalendar, utiliza la zona horaria de NSCalendar. Entonces, si quería ver qué hora era en Nueva York, cuando hoy comenzó en Los Ángeles, podría hacer esto:

 let losAngelesCalendar = NSCalendar.currentCalendar().copy() as! NSCalendar losAngelesCalendar.timeZone = NSTimeZone(name: "America/Los_Angeles")! let dateTodayBeganInLosAngeles = losAngelesCalendar.startOfDayForDate(NSDate()) dateTodayBeganInLosAngeles.timeIntervalSince1970 let dateFormatter = NSDateFormatter() dateFormatter.dateStyle = .MediumStyle dateFormatter.timeStyle = .ShortStyle dateFormatter.timeZone = NSTimeZone(name: "America/New_York")! let timeInNewYorkWhenTodayBeganInLosAngeles = dateFormatter.stringFromDate(dateTodayBeganInLosAngeles) print(timeInNewYorkWhenTodayBeganInLosAngeles) // prints "Jul 29, 2015, 3:00 AM" 
 NSCalendar *cal = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; [cal setTimeZone:[NSTimeZone systemTimeZone]]; NSDateComponents * comp = [cal components:( NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:[NSDate date]]; [comp setMinute:0]; [comp setHour:0]; [comp setSecond:0]; NSDate *startOfToday = [cal dateFromComponents:comp]; 

Si se refiere a la medianoche como a las 23:59, configure la hora del componente como 23 y los minutos como 59.

Puede usar el siguiente método para obtener el valor de medianoche para un NSDate.

 - (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate { // Use the user's current calendar and time zone NSCalendar *calendar = [NSCalendar currentCalendar]; NSTimeZone *timeZone = [NSTimeZone systemTimeZone]; [calendar setTimeZone:timeZone]; // Selectively convert the date components (year, month, day) of the input date NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:inputDate]; // Set the time components manually [dateComps setHour:0]; [dateComps setMinute:0]; [dateComps setSecond:0]; // Convert back NSDate *beginningOfDay = [calendar dateFromComponents:dateComps]; return beginningOfDay; } 

Thkis está tomado de este sitio web .

Rápido:

 let cal = NSCalendar.currentCalendar() //tip:NSCalendarUnit can be omitted, but with the presence of it, you can take advantage of Xcode's auto-completion var comps = cal.components(NSCalendarUnit.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit | .HourCalendarUnit | .MinuteCalendarUnit | .SecondCalendarUnit, fromDate: NSDate()) comps.hour = 0 comps.minute = 0 comps.second = 0 let midnightOfToday = cal.dateFromComponents(comps)! 

Swift 2.2:

 let cal = NSCalendar.currentCalendar() let comps = cal.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: NSDate()) comps.hour = 0 comps.minute = 0 comps.second = 0 let midnightOfToday = cal.dateFromComponents(comps)! 

C objective:

 NSCalendar *cal = [NSCalendar currentCalendar]; NSDateComponents *comps = [cal components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:[NSDate date]]; [comps setHour:0]; [comps setMinute:0]; [comps setSecond:0]; NSDate *midnightOfToday = [cal dateFromComponents:comps]; 

prueba esto:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *now = [NSDate date]; NSDateComponents *components = [gregorian components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:now]; NSDateFormatter* df = [[NSDateFormatter alloc]init]; [df setDateFormat:@"MM/dd/yyyy HH:mm:ss.SSS"]; NSLog(@"%@",[df stringFromDate:[gregorian dateFromComponents:components]]); 
 NSDate *now = [NSDate date]; NSDate *beginningOfToday = nil; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfToday interval:NULL forDate:now]; 

Podría usar NSCalendar ‘s dateBySettingHour:minute:second:ofDate:options:

Entonces sería tan fácil como hacer:

 NSCalendar *calendar = [NSCalendar currentCalendar]; calendar.timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; NSDate *midnight = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0]; 
  let calendar = NSCalendar.currentCalendar() let unitFlags: NSCalendarUnit = [.Year, .Month, .Day, .Minute, .Second] let components = calendar.components(unitFlags , fromDate: NSDate()) components.hour = 0 components.minute = 0 components.second = 0 //Gives Midnight time of today let midnightOfToday = calendar.dateFromComponents(components)! 

Desde iOS8, puedes usar startDayForDate.

Entonces, para comenzar hoy (Objective -C):

NSDate * midnight; midnight = [[NSCalendar currentCalendar] startOfDayForDate: [NSDate date]];