In previous installments in this series, we’ve covered:

**The basics of dates and times in Swift,**with creating dates, converting components into dates and vice versa, and converting dates into strings and vice versa,**date arithmetic in Swift,**with adding time intervals to dates and calculating the time between two dates, and**making date arithmetic in Swift more Swift-like**by harnessing the power of operator overloading and class extensions.

In this installment, we’ll make getting the time interval between two dates — which normally involves a lot of typing — a little more Swift-like.

**One common date arithmetic operation is to determine the interval between two given dates.** This is usually a clunky two-step process based on `NSCalendar`

‘s `components`

method, which expects at least three parameters:

- The time components you want the method to return, such as
`year`

s,`month`

s,`day`

s,`hour`

s,`minute`

s, and`second`

s. This is expressed by ORing together`NSCalendarUnit`

values, and - the two dates, in
`NSDate`

form.

Let’s look at how it works. First, we’ll need a couple of dates. Create a new playground and put the following code into it:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// Playground - noun: a place where people can play import UIKit let userCalendar = NSCalendar.currentCalendar() // Let's create some dates to work with // ==================================== // It's 3:45:30 a.m., New Year's Day. Time to go home. let goHomeYoureDrunkTimeComponents = NSDateComponents() goHomeYoureDrunkTimeComponents.year = 2015 goHomeYoureDrunkTimeComponents.month = 1 goHomeYoureDrunkTimeComponents.day = 1 goHomeYoureDrunkTimeComponents.hour = 3 goHomeYoureDrunkTimeComponents.minute = 45 goHomeYoureDrunkTimeComponents.second = 30 let goHomeYoureDrunkTime = userCalendar.dateFromComponents(goHomeYoureDrunkTimeComponents)! // Let's create an NSDate representing Bad Poetry Day (August 18) // at 4:20:10 p.m. let badPoetryDayComponents = NSDateComponents() badPoetryDayComponents.year = 2015 badPoetryDayComponents.month = 8 badPoetryDayComponents.day = 18 badPoetryDayComponents.hour = 16 badPoetryDayComponents.minute = 20 badPoetryDayComponents.second = 10 let badPoetryDay = userCalendar.dateFromComponents(badPoetryDayComponents)! |

In your playground’s sidebar, you should see the string representations of those dates:

`goHomeYoureDrunkTime`

should display as something like*January 1, 2015 at 3:45 a.m.,*and`badPoetryDay`

should display as something like*August 18, 2015 at 4:20 p.m.*.

Let’s find out how many days, hours, minutes, and seconds there are between `goHomeYoureDrunkTime`

and `badPoetryDay`

with the following code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// (Previous code goes here) // How many days, hours, minutes, and seconds between // goHomeYoureDrunkTime and badPoetryDay? let dayHourMinuteSecond: NSCalendarUnit = .DayCalendarUnit | .HourCalendarUnit | .MinuteCalendarUnit | .SecondCalendarUnit let difference = NSCalendar.currentCalendar().components( dayHourMinuteSecond, fromDate: goHomeYoureDrunkTime, toDate: badPoetryDay, options: nil) difference.day // 229 difference.hour // 12 difference.minute // 34 difference.second // 40 |

You should see from difference that there are 229 days, 12 hours, 34 minutes, and 40 seconds between the two dates. We did a lot of typing to get this result, and there should be a nicer way to do it. How about this:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// (Previous code goes here) // A date subtraction operation that returns an NSDateComponents // instance specifying the days, hours, miniutes and seconds // between two given NSDates // ============================================================= func -(lhs: NSDate, rhs: NSDate) -> NSDateComponents { let components: NSCalendarUnit = .SecondCalendarUnit | .MinuteCalendarUnit | .HourCalendarUnit | .DayCalendarUnit return NSCalendar.currentCalendar().components(components, fromDate: rhs, toDate: lhs, options: nil) } // Let's test it: let diff = badPoetryDay - goHomeYoureDrunkTime diff.day // 229 diff.hour // 12 diff.minute // 34 diff.second // 40 |

With this code, we’ve overloaded the `-`

operator, so that when both its operands are `NSDate`

s, iy returns an `NSDateComponents`

instance specifying the `day`

s, `hour`

s, `minute`

s, and `second`

s between the two. I could’ve coded it so that it also returned the time in terms of months and years, but the size of those units vary depending on the month and year, while days, hours, minutes, and seconds *always* represent the same amount of time.

{ 0 comments }