Search code examples
swiftios7nsdatenscalendarnsdatecomponents

NSCalendar.startOfDayForDate(date:) equivalent for iOS 7 with non-optional return type


Is it possible to change an NSDate object so that the result is equivalent to NSCalendar.startOfDayForDate(date:)? That method is only available to iOS 8 and newer, but I am looking for something that works on iOS 7.

I have looked at two methods:

  • NSCalendar.dateFromComponents(comps:) as described here: NSDate beginning of day and end of day. For instance, like this:

    class func startOfDay(date: NSDate, calendar: NSCalendar) -> NSDate {
      if #available(iOS 8, *) {
        return calendar.startOfDayForDate(date)
      } else {
        let dateComponents = calendar.components([.Year, .Month, .Day], fromDate: date)
        return calendar.dateFromComponents(dateComponents)!
      }
    }
    
  • NSDateFormatter.dateFromString(string:) by way of stringFromDate(date:), i.e. converting the NSDate object into a string without the time, then converting it back into an NSDate object.

The problem with both methods is that they return an optional NSDate. I am reluctant to unwrap this implicitly and I’d rather avoid changing the return type of the method within which these methods are called.


Solution

  • I think the calendar.components() method returns an optional, because you can theoretically enter components that do not create valid date, like 2000-02-30. If, as in your case, the components already come from a valid date, I would not be reluctant to implicitly unwrap the optional.