Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

theprizerevealed

macrumors regular
Original poster
Feb 26, 2016
183
12
hello all,

This is my programming problem: I need to be able to determine the number of hours and the number of minutes that are the difference between two times. My attempt to solve this problem used this code:

Code:
let time = "02:05"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let timeDate = dateFormatter.date(from: time)!
let tcalendar = Calendar.current
let timeComponents = tcalendar.dateComponents([.hour, .minute], from: timeDate)

let nowComponents = tcalendar.dateComponents([.hour, .minute], from: Date())

let differenceMinutes = tcalendar.dateComponents([.hour, .minute], from: timeComponents, to: nowComponents)

However, the problem is that this code finds only the difference between two times in a single day. If I try to find the difference between two times for two different days then the code produces the wrong answer.

For example, let's say that I wish to find the difference between 23:00 (European/Military time presentation style) of today and 01:00 of tomorrow (again the same presentation style). Then the answer produced would be 22 hours and 0 minutes instead of 2 hours and 0 minutes.

I am not very familiar with macOS/UNIX handling of timestamps and datestamps and it seems to challenge even experienced programmers.

Can someone suggest the correct strategy to solve my problem? Thank you
 

theprizerevealed

macrumors regular
Original poster
Feb 26, 2016
183
12
Just add .day do your dateComponents

Thanks, but this makes the number even larger. I wonder if that might be due to this line of code
Code:
dateFormatter.dateFormat = "HH:mm"

How would I write that to include day and/or the full calendar date? Then maybe your suggestion would work?
 

robvas

macrumors 68040
Mar 29, 2009
3,240
630
USA
Read up on DateComponent

 

theprizerevealed

macrumors regular
Original poster
Feb 26, 2016
183
12
Thank you, that is somewhat helpful. But I'm still trying to solve this issue. I should have elaborated more. I have a list of set times; midnight, 1 am, 2 am....all the way to 24 hours later at 11 pm. You are supposed to be able to select one of these times; all of which should be considered future times.

Now depending on the time of day that you are using the app; those future times might include a time that belongs to the next day. I cannot hardcode the future years, months and days into my app because it isn't feasible.

I need to devise a coding strategy that will account for the current exact year, month, day, hour and minute and - depending which future time is selected - then calculate the difference between that future time (which at most will be 1 day later) and the present time .

Somehow I need to assign the exact date of a future time to each entry of my list of future times. For example, 11pm tonight would be 2020 October 11 11pm or (2020 October 11 23:00). So that I can use the calendar components code to find the difference of the current time and the exact future time.

Any suggestions?
 

Red Menace

macrumors 6502a
May 29, 2011
583
230
Colorado, USA
You are trying to get a date from just a time string, so there isn't enough information. Use complete date objects, for example the current date, then add your time interval to it.
 

Mark FX

macrumors regular
Nov 18, 2011
159
17
West Sussex, UK
After reading your post a couple of times, I'm still struggling to get what your wanting to do.
But like "Red Menace" says, if your looking for a future date object based on the chosen time string.
Then you simply add a "TimeInterval" to the current date, which is passed as a "Double" of the seconds to add.
The problem is converting your time string to hours and minutes to add.

This code below is something that could get you started, although it could be done in several other ways.
With "dateComponents" or "dateFormatter" classes for example, but I've kept it basic with simple math.

Swift:
let time = "22:05" // future time required from Now
let timeComponents = time.components(separatedBy: ":")
let timeHour = Int(timeComponents.first!)
let timeMinute = Int(timeComponents.last!)
let timeSeconds = ((timeHour! * 3600) + (timeMinute! * 60))

let date = Date() // Current Date & Time Now
let dateHour = Calendar.current.component(.hour, from: date)
let dateMinute = Calendar.current.component(.minute, from: date)
let dateSeconds = ((dateHour * 3600) + (dateMinute * 60))

var futureInterval = Double() // Seconds to add for future date
if timeSeconds > dateSeconds {
    futureInterval = Double(timeSeconds - dateSeconds)
} else if timeSeconds < dateSeconds {
    let adjustmentSeconds = (24 * 3600) // Adjustment for 24 hour clock time settings
    //let adjustmentSeconds = (12 * 3600) // Adjustment for 12 hour clock time settings
    futureInterval = Double((timeSeconds + adjustmentSeconds) - dateSeconds)
}

let futureDate = date.addingTimeInterval(futureInterval) // new future Date object

let futureHours = Int(futureInterval) / 3600 // Hours added for future Date
let futureMinutes = (Int(futureInterval) / 60) % 60 // Minuts added for future Date

print("Future time added is \(futureHours) hours and \(futureMinutes) minutes")


Because your working with the future time as a string, the conversion to hours and minutes can be a problem.
And also you have to make adjustments for systems working in either 12 or 24 hour time formats.
which again can cause you problems if the user enters non valid times.
could you not use a "NSDatePicker" in your app, to allow the user to select a future date.

Hope this helps

Regards Mark
 
  • Love
Reactions: theprizerevealed

theprizerevealed

macrumors regular
Original poster
Feb 26, 2016
183
12
After reading your post a couple of times, I'm still struggling to get what your wanting to do.
But like "Red Menace" says, if your looking for a future date object based on the chosen time string.
Then you simply add a "TimeInterval" to the current date, which is passed as a "Double" of the seconds to add.
The problem is converting your time string to hours and minutes to add.

This code below is something that could get you started, although it could be done in several other ways.
With "dateComponents" or "dateFormatter" classes for example, but I've kept it basic with simple math.

Swift:
let time = "22:05" // future time required from Now
let timeComponents = time.components(separatedBy: ":")
let timeHour = Int(timeComponents.first!)
let timeMinute = Int(timeComponents.last!)
let timeSeconds = ((timeHour! * 3600) + (timeMinute! * 60))

let date = Date() // Current Date & Time Now
let dateHour = Calendar.current.component(.hour, from: date)
let dateMinute = Calendar.current.component(.minute, from: date)
let dateSeconds = ((dateHour * 3600) + (dateMinute * 60))

var futureInterval = Double() // Seconds to add for future date
if timeSeconds > dateSeconds {
    futureInterval = Double(timeSeconds - dateSeconds)
} else if timeSeconds < dateSeconds {
    let adjustmentSeconds = (24 * 3600) // Adjustment for 24 hour clock time settings
    //let adjustmentSeconds = (12 * 3600) // Adjustment for 12 hour clock time settings
    futureInterval = Double((timeSeconds + adjustmentSeconds) - dateSeconds)
}

let futureDate = date.addingTimeInterval(futureInterval) // new future Date object

let futureHours = Int(futureInterval) / 3600 // Hours added for future Date
let futureMinutes = (Int(futureInterval) / 60) % 60 // Minuts added for future Date

print("Future time added is \(futureHours) hours and \(futureMinutes) minutes")


Because your working with the future time as a string, the conversion to hours and minutes can be a problem.
And also you have to make adjustments for systems working in either 12 or 24 hour time formats.
which again can cause you problems if the user enters non valid times.
could you not use a "NSDatePicker" in your app, to allow the user to select a future date.

Hope this helps

Regards Mark


Thank you so much, this code appears to solve my problem completely! I figure that using the 'interval' code would play some role but I wasn't sure how...my gratitude!
 

Mark FX

macrumors regular
Nov 18, 2011
159
17
West Sussex, UK
theprizerevealed said:
Thank you so much, this code appears to solve my problem completely! I figure that using the 'interval' code would play some role but I wasn't sure how...my gratitude!

I'm pleased the posted code code works for you, so good luck with your project.

Mark
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.