Search code examples
iosnscalendarnstimeinterval

Neat way to get end of day for date?


I am querying a database for values between a startDate and an endDate. I am therefore looking for a neat way to get the NSDate for the end of the day for a date. Just like you can get startOfDayForDate().

I guess you could do :

let cal = NSCalendar.currentCalendar()
let startOfDay = cal.startOfDayForDate(NSDate())
let aDay:NSTimeInterval = 60*60*23 + 60*59 + 59
let endofDay = startOfDay.dateByAddingTimeInterval(aDay)

Is adding component.day + 1 to startOfDayForDate the correct method to get the "end of the day" for a date, or is there a better method?


Solution

  • A better way would be to get the start of the next day and subtract 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 second.

    Do you get what I want to say? It's very hard to define the end of the day. 23:59 is certainly not the end of the day, there is almost a whole minute left until the next day. And even 23:59:59 is not the end of a day. Because there is an infinite amount of fraction seconds between this time and the start of the next day. As far as I know NSDate supports nanoseconds out of the box, so in the current implementation there are at least 1 000 000 000 possible NSDates between 23:59:59 and the next day.

    That's why you should see if you can find a way to use the start of the next day.

    For example, instead of if (startOfDay <= date && date <= endOfDay) you could use if (startOfDay <= date && date < startOfNextDay).

    To calculate the start of the next day you have to use NSCalendar. In iOS8 Apple added a couple of nice methods to make these calculations short:

    let calendar = NSCalendar.currentCalendar()
    let startOfDay = calendar.startOfDayForDate(NSDate())
    let startOfNextDay = calendar.dateByAddingUnit(.CalendarUnitDay, value: 1, toDate: startOfDay, options: nil)!
    

    EDIT: Since you now state that you want to query a database you don't need to find the end of the day. Check if the date is on or after the start of the day, and before the start of the next day.