Convert NSTimeInterval to hours in decimals - ios

I'm working on an app, in which I take the difference between 2 NSdates, and get the interval in between using NSTimeInterval
let timediff = timeDownValue?.timeIntervalSinceDate(timeUpValue!)
then using my new timeDiff constant, I update my timeTotals var
var totalTime = NSTimeInterval()
Now, what I need to do from there is to convert this NSTimeInterval to a Decimal, because that's what they use to calculate the time. so for example if my interval between date1 and date2 is 30 minutes, I want my final output to be 0.5
I can't seems to figure out how
thanks

Your timediff variable is already a decimal value for the number of seconds. To convert that into hours, divide by 3600.
let timediff = timeDownValue?.timeIntervalSinceDate(timeUpValue!)
var totalTime = timediff / 3600.0
Here, totalTime will be in hours.

Related

Calculate percentage difference of 2 dates

I need to calculate the completion percentage between two dates. I have two dates: date1 and date2. When date1 catches up to date2, it should be 100%. Any days the current date is after date1, there should be some progress. E.g. everyday until date2 is met, there should be some sort of progress.
I am having difficulty in finding the percentage of two dates and their differences.
This is related to
drawing a circle using bezier path swift
So currently, I have the following:
let percentFull = 1 - Double(min(Int(components.day!), 20) / 20)
You want to use DateInterval, it can do most of the work for you:
let duration = DateInterval(start: startDate, end: endDate).duration
let complete = DateInterval(start: startDate, end: currentDate).duration
let percentComplete = complete / duration
If you want it to be in the form of 0-100 rather than 0-1:
let adjustedPercent = percentComplete * 100.0

Repeat Push Notification Every X Hours On The Hour

With UNCalendarNotificationTrigger I can get it to repeat at a specific hour every day.
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
With UNTimeIntervalNotificationTrigger I can get it to repeat by some interval from when the timer was created.
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: Double(frequency*60), repeats: true)
How though, can I get a push notification to repeat on the hour, at some flexible interval? For example, from 12:00am, every 2 hours, every 3 hours, or every 12 hours, and so on.
Well, if you know you can set a specific time to repeat at each day, why not calculate the times based on the interval yourself?
var components = DateComponents()
components.hour = 5
components.second = 0
let interval: Double = 60 * 30 // 30 min
let maxDuration: Double = 60 * 60 * 5 // 5 hours
let startDate = Calendar.current.date(
byAdding: components,
to: Calendar.current.startOfDay(for: Date()))
let endDate = startDate.addingTimeInterval(maxDuration)
let notificationCount: Int = Int((endDate.timeIntervalSince1970 - startDate.timeIntervalSince1970) / maxDuration)
(0..<notificationCount)
.map({ startDate.addingTimeInterval(Double($0) * interval) })
.forEach({ date in
// Schedule notification for each date here
})
You're going to have to manage the ranges and the day overlap yourself, but this should point you in the right direction.

DateComponentsFormatter - showing only hour described as minutes - bug?

I'm using DateComponentsFormatter to achieve something like that: "1 hour, 30 min". This is my code for that:
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .short
formatter.allowedUnits = [.hour, .minute]
return formatter.string(from: 90)!
This should return 1 hour and 30 minutes but my output is "1 min". Is something wrong with my code or is it iOS bug?
The DataComponentsFormatter string(from: TimeInterval) method that you are using expects the time interval in seconds.
So you are asking the formatter to format 90 seconds, not 90 minutes.
This will solve your issue:
return formatter.string(from: 90 * 60)! // 90 minutes
When ever in doubt about such things, read the documentation. The documentation shows the following for the parameter description:
The time interval, measured in seconds. The value must be a finite number. Negative numbers are treated as positive numbers when creating the string.

How to get time interval until date

I would like to get the time interval from the present date and time until a certain date in the future. All I could manage to do is get the interval but with a minus in front of all, because i used this:
let elapsedTime = NSDate().timeIntervalSinceDate(GeneralUtils.dateFromString(endDate))
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Abbreviated
let countdown = formatter.stringFromTimeInterval(elapsedTime)
timerLabel.text! = "\(countdown!)"
How could I fix it to show me the positive interval?
Now it shows me something like this "-1d 3h 23m 10s"
Just use abs() so the time interval is always positive. (Just me being insane)
Of course Russell points out you could just swap the dates around...
let elapsedTime = GeneralUtils.dateFromString(endDate).timeIntervalSinceNow

Setting multiple allowedUnits for NSDateComponenstFormatter in Swift

Background:
When formatting an NSTimeInterval using an NSDateComponentsFormatter, it's often handy to use the allowedUnits property to round the resulting string to a relevant time unit.
For example, I may not be interested in getting time to the second, so setting the allowedUnits to minutes gets an appropriately rounded output string:
let duration: NSTimeInterval = 3665.0 // 1 hour, 1 minute and 5 seconds
let durationFormatter = NSDateComponentsFormatter()
durationFormatter.unitsStyle = .Full
durationFormatter.zeroFormattingBehavior = .DropAll
durationFormatter.allowedUnits = .Minute
let formattedDuration = durationFormatter.stringFromTimeInterval(duration)
formattedDuration will be "61 Minutes".
The problem:
How would you go about setting allowedUnits to .Hour and .Minute so the formatted duration would be "1 hour, 1 minute" instead?
The NSDateComponentFormatter Class Reference doesn't really cover how to do this.
As suggested by Leo, you can simply provide the allowedUnits in an array like so:
durationFormatter.allowedUnits = [.Hour, .Minute]
The solution I've come up with is to create a NSCalendarUnit by adding the raw values of the desired allowed units together:
durationFormatter.allowedUnits = NSCalendarUnit(rawValue: NSCalendarUnit.Hour.rawValue + NSCalendarUnit.Minute.rawValue)
I't be interested to know if there's a better syntax or alternative way to do this.

Resources