In a recent iOS project written in Swift, I have frequently needed to add various intervals to NSDate
objects. Adding some number of seconds to an NSDate
is simple:
// Jan 1, 1970, 0:00 AM
let epoch = NSDate(timeIntervalSince1970: 0)
// Jan 1, 1970, 0:01 AM
epoch.dateByAddingTimeInterval(60)
If we start with an NSDate
initialized to the epoch, we call the dateByAddingTimeInterval
instance method with some number of seconds. If we want to instead add some number of days, any caller of the method has to calculate the number of seconds in a day.
let secondsInADay: NSTimeInterval = 60 * 60 * 24
// Jan 2, 1970, 0:00 AM
epoch.dateByAddingTimeInterval(secondsInADay)
Calculating the number of seconds in a day is simple, but it puts an unnecessary demand on the callers of the function. The demand becomes even more onerous when a caller wants to add multiple days to a date. Instead, let's add an extension to NSDate
to make the interface simpler.
extension NSDate {
func adding(days days: Int) -> NSDate {
let secondsInAMinute = 60
let secondsInAnHour = 60 * secondsInAMinute
let secondsInADay = 24 * secondsInAnHour
return self.dateByAddingTimeInterval(
NSTimeInterval(days * secondsInADay)
)
}
}
Now with our extension in place, we can add a day to any NSDate
as follows:
// Jan 2, 1970, 0:00 AM
epoch.adding(days: 1)
From here, it's fairly easy imagining how to improve our adding
function to include not just days, but also hours, minutes, seconds:
extension NSDate {
func adding(days days: Int = 0, hours: Int = 0, minutes: Int = 0, seconds: Int = 0) -> NSDate {
let secondsInAMinute = 60
let secondsInAnHour = 60 * secondsInAMinute
let secondsInADay = 24 * secondsInAnHour
return self.dateByAddingTimeInterval(
NSTimeInterval(days * secondsInADay) +
NSTimeInterval(hours * secondsInAnHour) +
NSTimeInterval(minutes * secondsInAMinute) +
NSTimeInterval(seconds)
)
}
}
Aside from the additional arguments, the one key difference with the code above is the addition of default values for the arguments. By having defaults, a caller can choose which intervals to pass into the function.