How to normalize NSDate objects (i.e. set the time to midnight)
When you create new date using [NSDate date] (i.e. today, as in right now) your date will save the current time as well as its date.
In fact, under the hood an NSDate object is the amount of seconds that have elapsed since the 1st of January 2001 (or 1970), in milliseconds. So really it’s a massive floating point number. You can see what it is with this code:
NSLog(@"Since 1970: %f", [today timeIntervalSince1970]); NSLog(@"Since 2001: %f", [today timeIntervalSinceReferenceDate]);
To save you the trouble, it’s bee roughly 1362585768.752258 seconds since 1970. But I digress…
Sometimes you want the date objects you’re dealing with not to regard “time” and really only deal with dates. As such, all dates – to be comparable – need to have the very same time, say midnight. Otherwise you may get the wrong results. Imagine adding three date objects that each have noon as their time, that’s an extra day and a half clouding your results right there.
Here’s some code that will normalize your NSDate object by setting its time to midnight:
// normalizing a date NSDate *yourDate = [NSDate date]; NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:yourDate]; yourDate = [gregorian dateFromComponents:dateComponents]; NSLog(@"Now your date starts at midnight: %@", yourDate);
In a nutshell, we “explode” the date into its year, month and day components, and then recreate a new object with these and no other components.