In this article, we’ll expand on material covered in the three previous articles in this series:

- The basic structs, which let us create dates and times, and work with their components. They are:
`Date`

, which represents a single point in time,`DateComponents`

, which represents the units that make up a date, such as year, month, day, hour, and minute, and which can be used to represent either a single point in time or a duration of time, and`Calendar`

, which provides a context for`Date`

s, and allows us to convert between`Date`

s and`DateComponents`

.

- The
`DateFormatter`

class, which converts`Date`

s into formatted`String`

s, and formatted`String`

s into`Date`

s. - Date arithmetic, which make it possible to add time intervals to
`Date`

s, find the difference in time between two`Date`

s, and compare`Date`

s.

## A more readable way to work with `Date`

s and `DateComponents`

Suppose we want to find out what the date and time will be 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds from now will be. If you recall what we covered in the last installment in this series, you’d probably use code like this:

1 2 3 4 5 6 7 |
var timeInterval = DateComponents() timeInterval.month = 2 timeInterval.day = 3 timeInterval.hour = 4 timeInterval.minute = 5 timeInterval.second = 6 let futureDate = Calendar.current.date(byAdding: timeInterval, to: Date())! |

In the code above, we did the following:

- We created an instance of a
`DateComponent`

s struct. - We set its properties so that it would represent a time interval of 2 months, 3 days, 4 hours, 5 minutes, and 6 seconds.
- We then used
`Calendar`

‘s`date(byAdding:to:)`

method to add the time interval to a`Date`

.

This code wouldn’t look out of place in a lot of other programming languages, but we can do better in Swift. What if I told you that by defining a few helper functions, you can turn the code above into the code below?

1 2 |
let coolerFutureDate = Date() + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds let coolerPastDate = Date() - 2.months - 3.days - 4.hours - 5.minutes - 6.seconds |

Or this code?

1 2 |
let coolerFutureDate = (2.months + 3.days + 4.hours + 5.minutes + 6.seconds).fromNow let coolerPastDate = (2.months + 3.days + 4.hours + 5.minutes + 6.seconds).ago |

I’d much rather write the code above. This article will cover the code necessary to make this kind of syntactic magic possible.

## Overloading `+`

and `-`

so that we can add and subtract `DateComponents`

First, let’s write some code that allows us to add and subtract `DateComponents`

. Start a new playground and enter 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 |
func +(_ lhs: DateComponents, _ rhs: DateComponents) -> DateComponents { return combineComponents(lhs, rhs) } func -(_ lhs: DateComponents, _ rhs: DateComponents) -> DateComponents { return combineComponents(lhs, rhs, multiplier: -1) } func combineComponents(_ lhs: DateComponents, _ rhs: DateComponents, multiplier: Int = 1) -> DateComponents { var result = DateComponents() result.second = (lhs.second ?? 0) + (rhs.second ?? 0) * multiplier result.minute = (lhs.minute ?? 0) + (rhs.minute ?? 0) * multiplier result.hour = (lhs.hour ?? 0) + (rhs.hour ?? 0) * multiplier result.day = (lhs.day ?? 0) + (rhs.day ?? 0) * multiplier result.weekOfYear = (lhs.weekOfYear ?? 0) + (rhs.weekOfYear ?? 0) * multiplier result.month = (lhs.month ?? 0) + (rhs.month ?? 0) * multiplier result.year = (lhs.year ?? 0) + (rhs.year ?? 0) * multiplier return result } |

In the code above, we’ve overloaded the + and – operators so that we can add and subtract `DateComponents`

. I derived these functions from Axel Schlueter’s *SwiftDateTimeExtensions* library. He wrote them when Swift was still in beta; I updated them so that they compile with the current version and added a couple of tweaks of my own.

The addition and subtraction operations are so similar and so tedious, which is a sign that there’s an opportunity to DRY up the code. I factored out the duplicate code from both the `+`

and `-`

overloads and put it into its own method, `combineComponents`

, which does the actual `DateComponents`

addition and subtraction.

You may have noticed a lot of `??`

operators in the code for `combineComponents`

. `??`

is referred to as the nil coalescing operator, and it’s a clever bit of syntactic shorthand. For the expression below:

`let finalValue = someOptionalValue ?? fallbackValue`

- If
`someOptionalValue`

is not`nil`

,`finalValue`

is set to`someOptionalValue`

‘s value. - If
`someOptionalValue`

is`nil`

,`finalValue`

is set to`fallbackValue`

‘s value.

Let’s confirm that our code works. Try out the following code:

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) // Let's define a couple of durations of time var oneDayFiveHoursTenMinutes = DateComponents() oneDayFiveHoursTenMinutes.day = 1 oneDayFiveHoursTenMinutes.hour = 5 oneDayFiveHoursTenMinutes.minute = 10 var threeDaysTenHoursThirtyMinutes = DateComponents() threeDaysTenHoursThirtyMinutes.day = 3 threeDaysTenHoursThirtyMinutes.hour = 10 threeDaysTenHoursThirtyMinutes.minute = 30 // Now let's add and subtract them let additionResult = OneDayFiveHoursTenMinutes + ThreeDaysTenHoursThirtyMinutes additionResult.day // 4 additionResult.hour // 15 additionResult.minute // 40 let subtractionResult = ThreeDaysTenHoursThirtyMinutes - OneDayFiveHoursTenMinutes subtractionResult.day // 2 subtractionResult.hour // 5 subtractionResult.minute // 20 |

## Overloading `-`

so that we can negate `DateComponents`

Now that we can add and subtract `DateComponents`

, let’s overload the unary minus so that we can negate `DateComponents`

:

1 2 3 4 5 6 7 8 9 10 11 12 13 |
// (Previous code goes here) prefix func -(components: DateComponents) -> DateComponents { var result = DateComponents() if components.second != nil { result.second = -components.second! } if components.minute != nil { result.minute = -components.minute! } if components.hour != nil { result.hour = -components.hour! } if components.day != nil { result.day = -components.day! } if components.weekOfYear != nil { result.weekOfYear = -components.weekOfYear! } if components.month != nil { result.month = -components.month! } if components.year != nil { result.year = -components.year! } return result } |

With this overload defined, we can now use the unary minus to negate `DateComponents`

:

1 2 3 4 5 6 |
// (Previous code goes here) let negativeTime = -oneDayFiveHoursTenMinutes negativeTime.day // -1 negativeTime.hour // -5 negativeTime.minute // -10 |

## Overloading `+`

and `-`

so that we can add `Date`

s and `DateComponents`

and subtract `DateComponents`

from `Date`

s

With the unary minus defined, we can now define the following operations:

`Date`

+`DateComponents`

`DateComponents`

+`Date`

`Date`

–`DateComponents`

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// (Previous code goes here) // Date + DateComponents func +(_ lhs: Date, _ rhs: DateComponents) -> Date { return Calendar.current.date(byAdding: rhs, to: lhs)! } // DateComponents + Dates func +(_ lhs: DateComponents, _ rhs: Date) -> Date { return rhs + lhs } // Date - DateComponents func -(_ lhs: Date, _ rhs: DateComponents) -> Date { return lhs + (-rhs) } |

Note that we didn’t define an overload for subtracting `Date`

from `DateComponents`

— such an operation doesn’t make any sense.

With these overloads defined, a lot of `Date`

/`DateComponents`

arithmetic in Swift becomes much easier to enter and read:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// (Previous code goes here) // What time will it be 1 day, 5 hours, and 10 minutes from now? // Here's the standard way of finding out: Calendar.current.date(byAdding: oneDayFiveHoursTenMinutes, to: Date()) // With our overloads and function definitions, we can now do it this way: Date() + oneDayFiveHoursTenMinutes // This will work as well: oneDayFiveHoursTenMinutes + Date() // What time was it 3 days, 10 hours, and 30 minutes ago? // Doing it the standard way takes some work var minus3Days5Hours30minutes = threeDaysTenHoursThirtyMinutes minus3Days5Hours30minutes.day = -threeDaysTenHoursThirtyMinutes.day! minus3Days5Hours30minutes.hour = -threeDaysTenHoursThirtyMinutes.hour! minus3Days5Hours30minutes.minute = -threeDaysTenHoursThirtyMinutes.minute! Calendar.current.date(byAdding: minus3Days5Hours30minutes, to: Date()) // With our overloads and function definitions, it's so much easier: Date() - threeDaysTenHoursThirtyMinutes |

## Extending `Date`

so that creating dates is simpler

Creating `Date`

s in Swift is a roundabout process. Usually, you end up creating them in one of two ways:

- Instantiating a
`DateComponents`

struct and then using it to create a`Date`

using`Calendar`

‘s`date(from:)`

method, or - Creating a
`String`

representation of the`Date`

and then using it to create a`Date`

using`DateFormatter`

‘s`date(from:)`

method.

Let’s simplify things by extending the `Date`

struct with a couple of convenient `init`

method overloads:

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 |
extension Date { init(year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0, second: Int = 0, timeZone: TimeZone = TimeZone(abbreviation: "UTC")!) { var components = DateComponents() components.year = year components.month = month components.day = day components.hour = hour components.minute = minute components.second = second components.timeZone = timeZone self = Calendar.current.date(from: components)! } init(dateString: String) { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd HH:mm:ss zz" self = formatter.date(from: dateString)! } } |

With these methods, initializing `Dates`

is a lot more simple:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// (Previous code goes here) // The Stevenote where the original iPhone was announced took place // on January 9, 2007 at 10:00 a.m. PST let iPhoneStevenoteDate = Date(year: 2007, month: 1, day: 9, hour: 10, minute: 0, second: 0, timeZone: TimeZone(abbreviation: "PST")!) // The original iPhone went on sale on June 27, 2007 let iPhoneReleaseDate = Date(year: 2007, month: 6, day: 27) // June 27, 2007, 00:00:00 UTC // The Stevenote where the original iPhone was announced took place // on January 27, 2010 at 10:00 a.m. PST let iPadStevenoteDate = Date(dateString: "2010-01-27 10:00:00 PST") |

## Overloading `-`

so that we can use it to find the difference between two `Date`

s

When we’re trying to determine the time between two given `Date`

s, what we’re doing is finding the difference between them. Wouldn’t it be nice if we could use the `-`

operator to find the difference between `Date`

s, just as we can use it to find the difference between numbers?

Let’s code an overload to do just that:

1 2 3 4 5 6 7 8 |
// (Previous code goes here) func -(_ lhs: Date, _ rhs: Date) -> DateComponents { return Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: lhs, to: rhs) } |

Let’s test it in action:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
let timeFromAnnouncementToRelease = iPhoneReleaseDate - iPhoneStevenoteDate timeFromAnnouncementToRelease.year // 0 timeFromAnnouncementToRelease.month // 5 timeFromAnnouncementToRelease.day // 17 timeFromAnnouncementToRelease.hour // 7 timeFromAnnouncementToRelease.minute // 0 // How long ago was the first moon landing, which took place // on July 20, 1969, 20:18 UTC? Date() - Date(dateString: "1969-07-20 20:18:00 UTC") // At the time of writing, this value was a Date with the following properties: // - year: 47 // - month: 1 // - day: 9 // - hour: 22 // - minute: 14 |

## Extending `Int`

to add some syntactic magic to date components

We’ve already got some syntactic niceties, but the real Swift magic happens when we add this code to the mix:

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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
// (Previous code goes here) extension Int { var second: DateComponents { var components = DateComponents() components.second = self; return components } var seconds: DateComponents { return self.second } var minute: DateComponents { var components = DateComponents() components.minute = self; return components } var minutes: DateComponents { return self.minute } var hour: DateComponents { var components = DateComponents() components.hour = self; return components } var hours: DateComponents { return self.hour } var day: DateComponents { var components = DateComponents() components.day = self; return components } var days: DateComponents { return self.day } var week: DateComponents { var components = DateComponents() components.weekOfYear = self; return components } var weeks: DateComponents { return self.week } var month: DateComponents { var components = DateComponents() components.month = self; return components } var months: DateComponents { return self.month } var year: DateComponents { var components = DateComponents() components.year = self; return components } var years: DateComponents { return self.year } } |

This additions to `Int`

allow us to convert `Int`

s to `DateComponents`

in an easy-to-read way, and with our overloads to add and subtract `DateComponents`

to and from each other, and to add `Date`

s to `DateComponents`

, we can now perform all sorts of syntactic magic like this:

1 2 3 4 5 6 7 8 9 |
// From our earlier test of Date subtraction, we know that // there were 5 months, 17 days, and 7 hours between // the Stevenote when the iPhone was announced and // midnight UTC on the day it was released. iPhoneStevenoteDate + 5.months + 17.days + 7.hours // June 27, 2007, 00:00:00 UTC // What was the date 10 years, 9 months, 8 days, 7 hours, and 6 minutes ago? Date() - 10.years - 9.months - 8.days - 7.hours - 6.minutes // At the time of writing, this value was Nov 22, 2005, 6:51 a.m. EST. |

## Extending `DateComponents`

to add even more syntactic magic: `fromNow`

and `ago`

And finally, a couple of additions to the `DateComponents`

struct to make `Date`

/`DateComponent`

calculations even more concise and readable:

1 2 3 4 5 6 7 8 9 10 11 12 13 |
extension DateComponents { var fromNow: Date { return Calendar.current.date(byAdding: self, to: Date())! } var ago: Date { return Calendar.current.date(byAdding: -self, to: Date())! } } |

Here are these additions in action:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
2.weeks.fromNow // At the time of writing, this value was // Sep 13, 2016, 2:55 PM 3.months.fromNow // At the time of writing, this value was // Nov 30, 2016, 2:55 PM (2.months + 3.days + 4.hours + 5.minutes + 6.seconds).fromNow // At the time of writing, this value was // Nov 2, 2016, 7:04 PM (2.months + 3.days + 4.hours + 5.minutes + 6.seconds).ago // At the time of writing, this value was // Nov 2, 2016, 7:04 PM |

## Wrapping it all up

Here’s the playground containing all the code we just worked with:

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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
import UIKit // Overloading + and - so that we can add and subtract DateComponents // ------------------------------------------------------------------ func +(_ lhs: DateComponents, _ rhs: DateComponents) -> DateComponents { return combineComponents(lhs, rhs) } func -(_ lhs: DateComponents, _ rhs: DateComponents) -> DateComponents { return combineComponents(lhs, rhs, multiplier: -1) } func combineComponents(_ lhs: DateComponents, _ rhs: DateComponents, multiplier: Int = 1) -> DateComponents { var result = DateComponents() result.second = (lhs.second ?? 0) + (rhs.second ?? 0) * multiplier result.minute = (lhs.minute ?? 0) + (rhs.minute ?? 0) * multiplier result.hour = (lhs.hour ?? 0) + (rhs.hour ?? 0) * multiplier result.day = (lhs.day ?? 0) + (rhs.day ?? 0) * multiplier result.weekOfYear = (lhs.weekOfYear ?? 0) + (rhs.weekOfYear ?? 0) * multiplier result.month = (lhs.month ?? 0) + (rhs.month ?? 0) * multiplier result.year = (lhs.year ?? 0) + (rhs.year ?? 0) * multiplier return result } // Let's define a couple of durations of time var oneDayFiveHoursTenMinutes = DateComponents() oneDayFiveHoursTenMinutes.day = 1 oneDayFiveHoursTenMinutes.hour = 5 oneDayFiveHoursTenMinutes.minute = 10 var threeDaysTenHoursThirtyMinutes = DateComponents() threeDaysTenHoursThirtyMinutes.day = 3 threeDaysTenHoursThirtyMinutes.hour = 10 threeDaysTenHoursThirtyMinutes.minute = 30 // Now let's add and subtract them let additionResult = oneDayFiveHoursTenMinutes + threeDaysTenHoursThirtyMinutes additionResult.day // 4 additionResult.hour // 15 additionResult.minute // 40 let subtractionResult = threeDaysTenHoursThirtyMinutes - oneDayFiveHoursTenMinutes subtractionResult.day // 2 subtractionResult.hour // 5 subtractionResult.minute // 20 // Overloading - so that we can negate DateComponents // -------------------------------------------------- // We'll need to overload unary - so we can negate components prefix func -(components: DateComponents) -> DateComponents { var result = DateComponents() if components.second != nil { result.second = -components.second! } if components.minute != nil { result.minute = -components.minute! } if components.hour != nil { result.hour = -components.hour! } if components.day != nil { result.day = -components.day! } if components.weekOfYear != nil { result.weekOfYear = -components.weekOfYear! } if components.month != nil { result.month = -components.month! } if components.year != nil { result.year = -components.year! } return result } let negativeTime = -oneDayFiveHoursTenMinutes negativeTime.day // -1 negativeTime.hour // -5 negativeTime.minute // -10 // Overloading + and - so that we can add Dates and DateComponents // and subtract DateComponents from Dates // Date + DateComponents func +(_ lhs: Date, _ rhs: DateComponents) -> Date { return Calendar.current.date(byAdding: rhs, to: lhs)! } // DateComponents + Dates func +(_ lhs: DateComponents, _ rhs: Date) -> Date { return rhs + lhs } // Date - DateComponents func -(_ lhs: Date, _ rhs: DateComponents) -> Date { return lhs + (-rhs) } // What time will it be 1 day, 5 hours, and 10 minutes from now? // Here's the standard way of finding out: Calendar.current.date(byAdding: oneDayFiveHoursTenMinutes, to: Date()) // With our overloads and function definitions, we can now do it this way: Date() + oneDayFiveHoursTenMinutes // This will work as well: oneDayFiveHoursTenMinutes + Date() // What time was it 3 days, 10 hours, and 30 minutes ago? // Doing it the standard way takes some work var minus3Days5Hours30minutes = threeDaysTenHoursThirtyMinutes minus3Days5Hours30minutes.day = -threeDaysTenHoursThirtyMinutes.day! minus3Days5Hours30minutes.hour = -threeDaysTenHoursThirtyMinutes.hour! minus3Days5Hours30minutes.minute = -threeDaysTenHoursThirtyMinutes.minute! Calendar.current.date(byAdding: minus3Days5Hours30minutes, to: Date()) // With our overloads and function definitions, it's so much easier: Date() - threeDaysTenHoursThirtyMinutes // Extending Date so that creating dates is simpler // ------------------------------------------------ extension Date { init(year: Int, month: Int, day: Int, hour: Int = 0, minute: Int = 0, second: Int = 0, timeZone: TimeZone = TimeZone(abbreviation: "UTC")!) { var components = DateComponents() components.year = year components.month = month components.day = day components.hour = hour components.minute = minute components.second = second components.timeZone = timeZone self = Calendar.current.date(from: components)! } init(dateString: String) { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd HH:mm:ss zz" self = formatter.date(from: dateString)! } } // The Stevenote where the original iPhone was announced took place // on January 9, 2007 at 10:00 a.m. PST let iPhoneStevenoteDate = Date(year: 2007, month: 1, day: 9, hour: 10, minute: 0, second: 0, timeZone: TimeZone(abbreviation: "PST")!) // The original iPhone went on sale on June 27, 2007 let iPhoneReleaseDate = Date(year: 2007, month: 6, day: 27) // June 27, 2007, 00:00:00 UTC // The Stevenote where the original iPhone was announced took place // on January 27, 2010 at 10:00 a.m. PST let iPadStevenoteDate = Date(dateString: "2010-01-27 10:00:00 PST") // Overloading - so that we can use it to find the difference between two Dates func -(_ lhs: Date, _ rhs: Date) -> DateComponents { return Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: rhs, to: lhs) } let timeFromAnnouncementToRelease = iPhoneReleaseDate - iPhoneStevenoteDate timeFromAnnouncementToRelease.year // 0 timeFromAnnouncementToRelease.month // 5 timeFromAnnouncementToRelease.day // 17 timeFromAnnouncementToRelease.hour // 7 timeFromAnnouncementToRelease.minute // 0 // How long ago was the first moon landing, which took place // on July 20, 1969, 20:18 UTC? Date() - Date(dateString: "1969-07-20 20:18:00 UTC") // At the time of writing, this value was a Date with the following properties: // - year: 47 // - month: 1 // - day: 9 // - hour: 22 // - minute: 14 // Extending Int to add some syntactic magic to date components // ------------------------------------------------------------ extension Int { var second: DateComponents { var components = DateComponents() components.second = self; return components } var seconds: DateComponents { return self.second } var minute: DateComponents { var components = DateComponents() components.minute = self; return components } var minutes: DateComponents { return self.minute } var hour: DateComponents { var components = DateComponents() components.hour = self; return components } var hours: DateComponents { return self.hour } var day: DateComponents { var components = DateComponents() components.day = self; return components } var days: DateComponents { return self.day } var week: DateComponents { var components = DateComponents() components.weekOfYear = self; return components } var weeks: DateComponents { return self.week } var month: DateComponents { var components = DateComponents() components.month = self; return components } var months: DateComponents { return self.month } var year: DateComponents { var components = DateComponents() components.year = self; return components } var years: DateComponents { return self.year } } // From our earlier test of Date subtraction, we know that // there were 5 months, 17 days, and 7 hours between // the Stevenote when the iPhone was announced and // midnight UTC on the day it was released. iPhoneStevenoteDate + 5.months + 17.days + 7.hours // June 27, 2007, 00:00:00 UTC // What was the date 10 years, 9 months, 8 days, 7 hours, and 6 minutes ago? Date() - 10.years - 9.months - 8.days - 7.hours - 6.minutes // At the time of writing, this value was Nov 22, 2005, 6:51 a.m. EST. // Extending DateComponents to add even more syntactic magic: fromNow and ago // -------------------------------------------------------------------------- extension DateComponents { var fromNow: Date { return Calendar.current.date(byAdding: self, to: Date())! } var ago: Date { return Calendar.current.date(byAdding: -self, to: Date())! } } 2.weeks.fromNow // At the time of writing, this value was // Sep 13, 2016, 2:55 PM 3.months.fromNow // At the time of writing, this value was // Nov 30, 2016, 2:55 PM (2.months + 3.days + 4.hours + 5.minutes + 6.seconds).fromNow // At the time of writing, this value was // Nov 2, 2016, 7:04 PM (2.months + 3.days + 4.hours + 5.minutes + 6.seconds).ago // At the time of writing, this value was // Nov 2, 2016, 7:04 PM |

{ 6 comments… read them below or add one }

That is so AMAZING! In other languages I use, it is much easier to deal with dates. But with your “magic”, it is pretty easy in Swift, too. :-)

Great tutorial. Thanks!

Nice work. Thx!

Thank you … very nice Tutorial! I’m deeply impressed :)

Hello there. I ve been reading you “How to work with dates and times in swift” article and I have a question.

I am able to compare for example the current date and my birth date and get an answer like this

“You are 12822 days old” or

“You are 35 years old”

What should i do if i want an answer like

“You are 35 years 1 month 25 days and 15 minutes old”?

Thanks!

So, I noticed you simply added force unwrap to all the Calendar functions. Not really clean. Is there not an other way?

{ 1 trackback }