Here are a couple of different ways to get the difference between dates in Swift.
If you want to create a string like “4 hours ago” or “5 months ago” and don’t want to specify the actual unit, it’s best to use RelativeDateTimeFormatter
.
RelativeDateTimeFormatter
was introduced in iOS 13 and uses the largest time measurement that makes sense.
Let’s take a look at some examples:
let exampleDate = Date().addingTimeInterval(-20000)
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date())
print(relativeDate)
This above example will print:
5 hours ago
Let’s take a look at an example of a time in the future:
let exampleDate = Date().addingTimeInterval(100000)
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date())
print(relativeDate)
in 1 day
You can use four different unit styles for the RelativeDateTimeFormatter
:
Full uses the full name of the date component:
formatter.unitsStyle = .full
let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date())
print(relativeDate)
// in 2 hours
Abbreviated does what you would expect… uses an abbreviated version of the date component:
formatter.unitsStyle = .abbreviated
let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date())
print(relativeDate)
// in 2 hr.
If you want to get the difference in the dates in a more specific time unit, read on.
In my testing, .short
is generally the same as .abbreviated
:
formatter.unitsStyle = .short
let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date())
print(relativeDate)
// in 2 hr.
Spell out replaces the number with a string:
formatter.unitsStyle = .spellOut
let relativeDate = formatter.localizedString(for: exampleDate, relativeTo: Date())
print(relativeDate)
// in two hours
What if you want to get difference between dates in days, minutes and seconds?
You can use this Date
extension function to get that done:
extension Date {
func offset(from date: Date) -> String {
let dayHourMinuteSecond: Set<Calendar.Component> = [.day, .hour, .minute, .second]
let difference = NSCalendar.current.dateComponents(dayHourMinuteSecond, from: date, to: self)
let seconds = "\(difference.second ?? 0)s"
let minutes = "\(difference.minute ?? 0)m" + " " + seconds
let hours = "\(difference.hour ?? 0)h" + " " + minutes
let days = "\(difference.day ?? 0)d" + " " + hours
if let day = difference.day, day > 0 { return days }
if let hour = difference.hour, hour > 0 { return hours }
if let minute = difference.minute, minute > 0 { return minutes }
if let second = difference.second, second > 0 { return seconds }
return ""
}
}
Here’s an example on how to use this function:
let date1 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 05, day: 20, hour: 5, minute: 45).date!
let difference = date2.offset(from: date1)
print(difference) // 140d 5h 45m 0s
Let’s create an extension to calculate the difference between dates in seconds:
extension Date {
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
}
Here’s an example using this new extension method:
let date1 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 01, day: 20, hour: 0, minute: 0).date!
let seconds = date2.seconds(from: date1)
print(seconds) // 1641600
To calculate the difference between dates in minutes, use this Date
extension function:
extension Date {
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
}
Now here’s an example using this method:
let date1 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 01, day: 20, hour: 0, minute: 0).date!
let minutes = date2.minutes(from: date1)
print(minutes) // 27360
To calculate the difference between dates in hours use this Date
extension function:
extension Date {
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
}
Now here’s an example using this method:
let date1 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 20, minute: 0).date!
let hours = date2.hours(from: date1)
print(hours) // 20
To get the difference between dates in days, create this extension function for the Date
class:
extension Date {
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
}
Here is an example of using this extension to get the days between dates in Swift:
let date1 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 01, day: 20, hour: 0, minute: 0).date!
let days = date2.days(from: date1)
print(days) // 19
To get the difference in weeks between dates in Swift, create this Date
class extension:
extension Date {
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
}
Here’s how to use this extension:
let date1 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 01, day: 20, hour: 0, minute: 0).date!
let weeks = date2.weeks(from: date1)
print(weeks) // 2
Note that this does not count fractional or partial weeks! Here’s a solution that returns both weeks and days.
Create this Date
class extension to get the difference in months:
extension Date {
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
}
Here’s how to use this extension:
let date1 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 10, day: 01, hour: 0, minute: 0).date!
let months = date2.months(from: date1)
print(months) // 9
Create this Date
class extension to get the difference in months:
extension Date {
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
}
Here’s how to use this extension:
let date1 = DateComponents(calendar: .current, year: 2010, month: 01, day: 01, hour: 0, minute: 0).date!
let date2 = DateComponents(calendar: .current, year: 2020, month: 01, day: 01, hour: 0, minute: 0).date!
let years = date2.years(from: date1)
print(years) // 10
The Complete iOS App Development Bootcamp
Disclosure: This website may contain affiliate links, meaning when you click the links and make a purchase, we receive a commission.