Search code examples
iosdatetimensdatenscalendarnsdatecomponents

NSDate setting the time, not the expected result


I have the following code to set the time on a date to 0 hours, 0 minutes, 0 seconds by using the YEAR, MONTH and DAY components from the date to construct a new one:

NSDate *date = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit) fromDate:date];
NSDate *newDate = [gregorian dateFromComponents:comps];
NSLog(@"date: %@, newDate: %@", date, newDate);

The output is:

date: 2012-11-06 11:44:09 +0000, newDate: 2012-11-05 23:00:00 +0000

but I was expecting the new date to be: 2012-11-06 00:00:00 +0000 What's happening that I should know of?


Solution

  • NSLog shows the dates using -[NSDate description] which, in turn, converts the absolute time stored in the NSDate to a string. This conversion is done using UTC as the time zone.

    For you case it's probably best to do the date calculations in UTC as well. To do so adjust the calendar object that does the calculations:

    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    [gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];