How to calculate time (minutes) between two dates in swift?

Viewed 7550

What do we got: Date+time (format yyyy-mm-dd hh:mm a)

What are we looking for: Time difference in minutes

What operation: NewDate - OldDate

So, I wonder how I could accomplish above goal? I would like to format the date and time to US, regardless from which locale the user has. How can I do that?

Then I will save the 'oldTime' into UserDefaults, and use it for later calculation. The goal is to put the user on delay for 5 minutes and the calculations will be performed to determine if user should be on delay or not.

3 Answers

Just make a function that takes two dates and compares them like this.

import UIKit


func minutesBetweenDates(_ oldDate: Date, _ newDate: Date) -> CGFloat {

    //get both times sinces refrenced date and divide by 60 to get minutes
    let newDateMinutes = newDate.timeIntervalSinceReferenceDate/60
    let oldDateMinutes = oldDate.timeIntervalSinceReferenceDate/60

    //then return the difference
    return CGFloat(newDateMinutes - oldDateMinutes)
}


//Usage:

let myDateFormatter = DateFormatter()
myDateFormatter.dateFormat = "yyyy-MM-dd HH:mm"

//You'll need both dates to compare, you can get them by just storing a Date object when you first start the timer.
//Then when you need to check it, compare it to Date()
let oldDate: Date = myDateFormatter.date(from: String("2019-06-22 11:25"))

func validateRefresh() {

    //do the comparison between the old date and the now date like this.
    if minutesBetweenDates(oldDate, Date()) > 5 {
        //Do whatever
    }
}

You can, of course, change the .dateFormat value on the date formatter to be whatever format you'd like. A great website for finding the right format is: https://nsdateformatter.com/.

You say:

I would like to format the date and time to US, regardless from which locale the user has. How can I do that?

Specify a Locale of en_US_POSIX:

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd hh:mm a"
formatter.locale = Locale(identifier: "en_US_POSIX")

The locale is not the only question.

  • There’s also a timezone question. For example, you're driving out of Chicago and go from Central to Eastern timezones; do you really want to consider that one hour has passed?

  • Do you really want to discard seconds? If you do that, the 59 seconds between going from 8:00:00pm to 8:00:59pm will be considered “zero minutes” but the one second between 8:00:59pm and 8:01:00pm will be considered “one minute”.

Frankly, if I wanted to save a locale and timezone invariant date string, I’d suggest using ISO8601DateFormatter.

Then I will save the 'oldTime' into UserDefaults, and use it for later calculation.

If that’s why you’re using this DateFormatter, I’d suggest saving the Date object directly.

UserDefaults.standard.set(oldTime, forKey: "oldTime")

And to retrieve it:

if let oldTime = UserDefaults.standard.object(forKey: "oldTime") as? Date {
    ...
}

In terms of calculating the number of minutes between two Date objects

let minutes = Calendar.current
    .dateComponents([.minute], from: date1, to: date2)
    .minute

If you want the number of seconds, you can also use timeIntervalSince:

let seconds = date2.timeIntervalSince(date1)

And if you wanted to show the amount of elapsed time as a nice localized string:

let intervalFormatter = DateComponentsFormatter()
intervalFormatter.allowedUnits = [.minute, .second]
intervalFormatter.unitsStyle = .full
let string = intervalFormatter.string(from: date1, to: date2)

I'm not convinced that your question is the best way to go about accomplishing your aim, but the code below will work.

let dateFormatterNow = DateFormatter()
dateFormatterNow.dateFormat = "yyyy-MM-dd hh:mm a"
dateFormatterNow.timeZone = TimeZone(abbreviation: "EST")

let oldDateString = "2019-06-23 12:44 p"
let oldDate = dateFormatterNow.date(from: oldDateString)

let newDateString = "2019-06-23 12:54 p"
let newDate = dateFormatterNow.date(from: newDateString)

if let oldDate = oldDate, let newDate = newDate {
    let diffInMins = Calendar.current.dateComponents([.minute], from: oldDate, to: newDate).minute
    print(diffInMins)
}
Related