How can I get an NSDate object for today at midnight?

Objective CCocoa TouchNsdate

Objective C Problem Overview


What is the most efficient way to obtain an NSDate object that represents midnight of the current day?

Objective C Solutions


Solution 1 - Objective C

New API in iOS 8

iOS 8 includes a new method on NSCalendar called startOfDayForDate, which is really easy to use:

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

Apple's description:

> This API returns the first moment date of a given date. Pass in [NSDate date], for example, if you want the start of "today". If there were two midnights, it returns the first. If there was none, it returns the first moment that did exist.

Update, regarding time zones:

Since startOfDayForDate is a method on NSCalendar, it uses the NSCalendar's time zone. So if I wanted to see what time it was in New York, when today began in Los Angeles, I could do this:

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"

Solution 2 - Objective C

Try this:

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];

Solution 3 - Objective C

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]; 

If you mean midnight as 23:59 then set component's hour as 23 and minutes as 59.

Solution 4 - Objective C

Swift:

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)!

Objective-C:

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];

Solution 5 - Objective C

You could use the following method to get the midnight value for an 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 is taken from here website.

Solution 6 - Objective C

From iOS8, you can use startDayForDate.

So, in order to get the start of today (Objective -C):

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

Solution 7 - Objective C

try this:

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]]);

Solution 8 - Objective C

NSDate *now = [NSDate date];
NSDate *beginningOfToday = nil;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginningOfToday interval:NULL forDate:now];

Solution 9 - Objective C

    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)!

Solution 10 - Objective C

You could use NSCalendar's dateBySettingHour:minute:second:ofDate:options:

So it would be as easy as doing:

NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];

NSDate *midnight = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmarkdorisonView Question on Stackoverflow
Solution 1 - Objective CRichard VenableView Answer on Stackoverflow
Solution 2 - Objective CChristian SchnorrView Answer on Stackoverflow
Solution 3 - Objective CaslisabanciView Answer on Stackoverflow
Solution 4 - Objective Cfujianjin6471View Answer on Stackoverflow
Solution 5 - Objective CAlex StanciuView Answer on Stackoverflow
Solution 6 - Objective CjoanView Answer on Stackoverflow
Solution 7 - Objective CDyorgioView Answer on Stackoverflow
Solution 8 - Objective CQiulangView Answer on Stackoverflow
Solution 9 - Objective CMohammad YaqoobView Answer on Stackoverflow
Solution 10 - Objective CThecafremoView Answer on Stackoverflow