Getting the Difference Between Two Dates (Months/Days/Hours/Minutes/Seconds) in Swift

Getting the difference between two Dates (months/days/hours/minutes/seconds) in Swift

Xcode 8.3 • Swift 3.1 or later

You can use Calendar to help you create an extension to do your date calculations as follow:

extension Date {
/// Returns the amount of years from another date
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}

Using Date Components Formatter

let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth, .month, .year]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = .full
dateComponentsFormatter.string(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"


let date1 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date2 = DateComponents(calendar: .current, year: 2015, month: 8, day: 28, hour: 5, minute: 9).date!

let years = date2.years(from: date1) // 0
let months = date2.months(from: date1) // 9
let weeks = date2.weeks(from: date1) // 39
let days = date2.days(from: date1) // 273
let hours = date2.hours(from: date1) // 6,553
let minutes = date2.minutes(from: date1) // 393,180
let seconds = date2.seconds(from: date1) // 23,590,800

let timeOffset = date2.offset(from: date1) // "9M"

let date3 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date4 = DateComponents(calendar: .current, year: 2015, month: 11, day: 28, hour: 5, minute: 9).date!

let timeOffset2 = date4.offset(from: date3) // "1y"

let date5 = DateComponents(calendar: .current, year: 2017, month: 4, day: 28).date!
let now = Date()
let timeOffset3 = now.offset(from: date5) // "1w"

Calculating the difference between two dates in Swift

I ended up creating a custom operator for Date:

extension Date {

static func - (lhs: Date, rhs: Date) -> TimeInterval {
return lhs.timeIntervalSinceReferenceDate - rhs.timeIntervalSinceReferenceDate
}

}

With this operator I can now compute the difference between two dates on a more abstract level without caring about timeIntervalSinceReferenceDate or what exactly the reference date is – and without losing precision, for example:

let delta = toDate - fromDate

Obviously, I didn't change much, but for me it's a lot more readable and consequent: Swift has the + operator already implemented for a Date and a TimeInterval:

/// Returns a `Date` with a specified amount of time added to it.
public static func + (lhs: Date, rhs: TimeInterval) -> Date

So it's already supporting

Date + TimeInterval = Date

Consequently, it should also support

Date - Date = TimeInterval

in my opinion and that's what I added with the simple implementation of the - operator. Now I can simply write the example function exactly as mentioned in my question:

func computeNewDate(from fromDate: Date, to toDate: Date) -> Date    
let delta = toDate - fromDate // `Date` - `Date` = `TimeInterval`
let today = Date()
if delta < 0 {
return today
} else {
return today + delta // `Date` + `TimeInterval` = `Date`
}
}

It might very well be that this has some downsides that I'm not aware of at this moment and I'd love to hear your thoughts on this.

Getting the difference in two dates - Swift

Change all of your NSDate to Date, then replace your requestedComponent with this:

let requestedComponent: Set<Calendar.Component> = [ .month, .day, .hour, .minute, .second]

Your difference will be:

let timeDifference = userCalendar.dateComponents(requestedComponent, from: startTime, to: endTime!)

FYI: Your dateFormatter doesn't work with this "25/12/16 00:00:00"
here is your whole class in correct form:

class ViewController: UIViewController {

@IBOutlet weak var dateLabelOutlet: UILabel!

let currentDate = Date()
let dateFormatter = DateFormatter()

let userCalendar = Calendar.current

let requestedComponent: Set<Calendar.Component> = [.month,.day,.hour,.minute,.second]

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}

func printTime() {
dateFormatter.dateFormat = "dd/MM/yy hh:mm:ss"
let startTime = Date()
let endTime = dateFormatter.date(from: "25/12/16 00:00:00")
let timeDifference = userCalendar.dateComponents(requestedComponent, from: startTime, to: endTime!)

dateLabelOutlet.text = "\(timeDifference.month) Months \(timeDifference.day) Days \(timeDifference.minute) Minutes \(timeDifference.second) Seconds"
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Calculating the number of days between two dates in swift

It has to do with the order that you're creating your variables and comparing them.

The first thing you do is create today. Then, you create twoWeeksFromNow, based on a new Date() that will be slightly further in the future than today was. On my machine, in a playground, the second date is about 300 microseconds further in the future than the first.

Then, for numDaysWithDate, you compare twoWeeksFromNow to another new Date(), even more slightly in the future. So, your time frame is very slightly less than 2 full weeks, giving you 13 days.

But, for numDaysWithToday, you compare twoWeeksFromNow with the original today, which was created before twoWeeksFromNow was, making it slightly longer than 2 weeks, giving you 14 days.

If you change the order of the the today and twoWeeksFromNow declarations, you can see a different result:

var twoWeeksFromNow: Date = Calendar.current.date(byAdding: .day,
value: 14, to: Date())!
var today = Date()

Now, because today was created slightly later than the date that twoWeeksFromNow was created from, both results are 13.

Swift - Find Difference Between Upcoming Time and Current Time

once you have your dates from the strings, you coud do something like this using component:

EDIT, using Alexander suggestion:

struct ContentView: View {
@State var timediff = ""
var body: some View {
Text(timediff)
.onAppear {
let RFC3339DateFormatter = DateFormatter()
RFC3339DateFormatter.locale = Locale(identifier: "en_US_POSIX")
RFC3339DateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
RFC3339DateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

let string1 = "1996-12-19T16:39:57-08:00"
let date1 = RFC3339DateFormatter.date(from: string1)
let string2 = "1996-12-19T13:19:27-08:00"
let date2 = RFC3339DateFormatter.date(from: string2)

if let d1 = date1, let d2 = date2 {
let result = Calendar.current.dateComponents([.hour, .minute], from: d1, to: d2)
timediff = result.description
}
}
}


Difference between 2 dates in weeks and days using swift 3 and xcode 8

You can use Calendar's dateComponents(_:from:to:) to find the difference between 2 dates to your desired units.

Example:

let dateRangeStart = Date()
let dateRangeEnd = Date().addingTimeInterval(12345678)
let components = Calendar.current.dateComponents([.weekOfYear, .month], from: dateRangeStart, to: dateRangeEnd)

print(dateRangeStart)
print(dateRangeEnd)
print("difference is \(components.month ?? 0) months and \(components.weekOfYear ?? 0) weeks")


> 2017-02-17 10:05:19 +0000
> 2017-07-10 07:26:37 +0000
> difference is 4 months and 3 weeks

let months = components.month ?? 0
let weeks = components.weekOfYear ?? 0


Related Topics



Leave a reply



Submit