1

I want to calculate time difference between 2 dates, and the time difference result must be something like

7h 12m OR 4 d 5h 27m OR 1M 5d 3h 21m

I have tried to write a function like this:

import UIKit

func calculateTimeDifference(from dateTime1: String, to dateTime2: String) -> String {

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

    let dateAsString = dateTime1
    let date1 = dateFormatter.date(from: dateAsString)!

    let dateAsString2 = dateTime2
    let date2 = dateFormatter.date(from: dateAsString2)!

    let components : NSCalendar.Unit = [.second, .minute, .hour, .day, .weekOfMonth, .month, .year]
    let difference = (Calendar.current as NSCalendar).components(components, from: date1, to: date2, options: [])

    var dateTimeDifferenceString = ""

    if difference.day != 0 {
        dateTimeDifferenceString = "\(difference.day!)d \(difference.hour!)h \(difference.minute!)m"
    } else if  difference.day == 0 {
        dateTimeDifferenceString = "\(difference.hour!)h \(difference.minute!)m"
    }

    return dateTimeDifferenceString
}

but when I implement this code

let checkinTime = "2018-02-09 07:51:01"
let now = "2018-02-20 14:56:18"

calculateTimeDifference(from: checkinTime, to: now) 

// Result: "4d 7h 5m"

I don't know why it just 4 days instead of 11 days

but if I implement it in the same day, it gives correct result

let checkinTime = "2018-02-09 07:51:01"
let now = "2018-02-09 14:56:18"

calculateTimeDifference(from: checkinTime, to: now)
// "7h 5m"

what went wrong in here?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Alexa289
  • 8,089
  • 10
  • 74
  • 178
  • 1
    Possible duplicate of [Getting the difference between two NSDates in (months/days/hours/minutes/seconds)](https://stackoverflow.com/questions/27182023/getting-the-difference-between-two-nsdates-in-months-days-hours-minutes-seconds) – Rocky Feb 09 '18 at 08:34

2 Answers2

2

In your first case, the difference between the dates is one week and four days, you'll see that if you print the computed date components.

print(difference)
// year: 0 month: 0 day: 4 hour: 7 minute: 5 second: 17 weekOfMonth: 1 isLeapMonth: false
//                  ^^^^^^                              ^^^^^^^^^^^^^^

So that's why you get the output "4d 7h 5m" instead of the expected "11d 7h 5m". To solve the problem, just remove .weekOfMonth from the calendar units:

let components : NSCalendar.Unit = [.second, .minute, .hour, .day, .month, .year]

In addition, you can work with Calendar directly, without bridging to NSCalendar:

let components: Set<Calendar.Component> = [.second, .minute, .hour, .day, .month, .year]
let difference = Calendar.current.dateComponents(components, from: date1, to: date2)
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
0

Please find working solution:

    func calculateTimeDifference(from dateTime1: String, to dateTime2: String) -> String {
                   let dateFormatter = DateFormatter()
                   dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
                            
                   let dateAsString = dateTime1
                   let date1 = dateFormatter.date(from: dateAsString)!
                            
                   let dateAsString2 = dateTime2
                   let date2 = dateFormatter.date(from: dateAsString2)!
                            
                   let components : NSCalendar.Unit = [.second, .minute, .hour, .day,.month, .year]
                   let difference = (Calendar.current as NSCalendar).components(components, from: date1, to: date2, options: [])
                            
                   var dateTimeDifferenceString = ""
                            
                   if difference.day != 0 {
                               dateTimeDifferenceString = "\(difference.day!)d \(difference.hour!)h \(difference.minute!)m"
                       } else if  difference.day == 0 {
                               dateTimeDifferenceString = "\(difference.hour!)h \(difference.minute!)m"
                       }
                            
                   return dateTimeDifferenceString
                            
           }

And call this function using this code:

        let checkinTime = "2018-02-09 07:51:01"

        let now = "2018-02-20 14:56:18"

        self.calculateTimeDifference(from: checkinTime, to: now)

So you will get exact difference date.