Convert decimal to hours:minutes:seconds - swift

I am storing numbers in a MySQL DB as doubles so I can get min, max and sums.
I have a decimal number 1.66777777778 which equals 01:40:04 however I am wanting to be able to convert this decimal in to hour:minutes:seconds in Swift so I can display the value as 01:40:04 however I don't know how.
I have done some searching but most results are calculators without explanation.
I have this function to convert to decimal:
func timeToHour(hour: String, minute:String, second:String) -> Double
{
var hourSource = 0.00
if hour == ""
{
hourSource = 0.00
}
else
{
hourSource = Double(hour)!
}
let minuteSource = Double(minute)!
let secondSource = Double(second)!
let timeDecimal: Double = hourSource + (minuteSource / 60) + (secondSource / 3600)
return timeDecimal
}
but need one to go back the other way.
Thanks

Try:
func hourToString(hour:Double) -> String {
let hours = Int(floor(hour))
let mins = Int(floor(hour * 60) % 60)
let secs = Int(floor(hour * 3600) % 60)
return String(format:"%d:%02d:%02d", hours, mins, secs)
}
Basically break each component out and concatenate them all together.

Related

Convert Minutes to HH:MM:SS - Swift

I have some text fields in an array. HH:MM:SS. I'm having two issues, one is when one of the fields is left blank, the app crashes and I want it to just read as "0" if blank. Second, I use below to convert HH:MM:SS to Minutes. I do 0:18:30 and the math below to decimal comes out to 18.5
Now how would I convert this back to HH:MM:SS? array[0] is hours, array[1] is minutes, array[2] is seconds.
stepOne = (Float(array[0])! * 60) + Float(array[1])! + (Float(array[2])! / 60)
What you need is to calculate the number of seconds instead of number of minutes. Using the reduce method just multiply the first element by 3600 and then divide the multiplier by 60 after each iteration. Next you can use DateComponentsFormatter to display the resulting seconds time interval using .positional units style to the user:
let array = [0,18,30]
var n = 3600
let seconds = array.reduce(0) {
defer { n /= 60 }
return $0 + $1 * n
}
let dcf = DateComponentsFormatter()
dcf.allowedUnits = [.hour, .minute, .second]
dcf.unitsStyle = .positional
dcf.zeroFormattingBehavior = .pad
let string = dcf.string(from: TimeInterval(seconds)) // "00:18:30"

Get double hours from double minute in Swift 2

I'm using Swift 2. I have double myMinute and I want to convert it to double hours(myHours). How can I do it? My codes under below
let myMinute : Double = 62.0
let myHours : Double = ?
I want to show with math example: myhours = 1.0
Found this here!
func minutesToHoursMinutes (minutes : Int) -> (hours : Int , leftMinutes : Int {
return (minutes / 60, (minutes % 60))
}
let timeTuple = minutesToHoursMinutes(minutes: 100)
timeTuple.hours /// 1
timeTuple.leftMinutes /// 40
The value should be 1.03 not 1.02 if you use the current value of minute (you can check with calculator) and it is a simple math, i think what you want beside the calculation is how to round the value to 2 decimal point. You should've made it clearer. This will do the work.
myHours = Double(round(myMinute / 60 * 100) / 100)
print(myHours)

Convert pounds to pound decimals in Swift (2.2)

How can I convert pounds to pound decimals?
For instance if the user enters 1.8 lbs, I would like to be able to convert it to 1.5 lbs so I can do some calculations.
The code below has two issues.
1- It only works when the user enters less then 10 (e.g 1.9) ounces since I'm multiplying the ounces by 10.
2- It only returns the decimal ounces, It does not return the whole number (pounds).
func poundsToDecimals(pounds:Double)->Double{
let ounces = Double(pounds % 1)
let decimals = ounces / 16 * 10
return decimals
}
print(poundsToDecimals(1.4)) //prints... 0.25
To solve your first problem try converting it the number into a String and then split it up like so:
func poundsToDecimals(pounds: Double) -> Double {
let numberAsString = String(pounds)
var numbers = numberAsString.components(separatedBy: ["."])
let seperatedPounds = Double(numbers[0])!
let ounces = Double(numbers[1])!
let decimals = ounces / 16 * 10
return decimals
}
Can you please specify your second problem further. if you want to return more then one value you usally do it like this.
func poundsToDecimals(pounds: Double) -> (Double, Double) {
let numberAsString = String(pounds)
var numbers = numberAsString.components(separatedBy: ["."])
let seperatedPounds = Double(numbers[0])!
let ounces = Double(numbers[1])!
let decimals = ounces / 16 * 10
return (decimals, seperatedPounds)
}
Hope that helps

Calculate average pace

I need to convert a decimal hour in to hh:mm:ss to display as average pace for a walking app.
I have converted the time to decimal and I have calculated the pace in to decimal however I am unsure how to convert this to time.
My timeDecimal is:
let timeDecimal:Double = (hourSource + (minuteSource / 60) + (secondSource / 3600)) / distanceSource
which gives me something like 0.4375
0 = 0
.4375 * 60 = 26.25
.25 = * 60 = 15
I know the time should be 00:26:15 but not sure the formula to achieve this without splitting up the result and performing the multiplication multiple times.
Any help is appreciated.
let formatter = NSDateComponentsFormatter()
formatter.allowedUnits = [ .Hour, .Minute, .Second ]
formatter.unitsStyle = .Positional
formatter.zeroFormattingBehavior = .Pad
let string = formatter.stringFromTimeInterval(0.4375 * 3600)!
Result: 0:26:15.
Try
var mytime = timeDecimal * 60
var minutes = floor(mytime)
var seconds = (mytime - minutes) * 60
func timeStringFrom(time time: Int) -> String {
let HoursLeft = time/3600
let MinutesLeft = (time%3600)/60
let SecondsLeft = (((time%3600)%60)%60)
if HoursLeft == 0 {
return String(format:"%.2d:%.2d", MinutesLeft, SecondsLeft)
} else {
return String(format:"%2d:%.2d:%.2d", HoursLeft, MinutesLeft, SecondsLeft)
}
}
Note: I'll probably turn it into a generic function soon

AVAudioPlayer currentTime exceeds duration

I'm making my own audio player using AVAudioPlayer.
NOTE: "p" is my instance of the player
Here's how I'm reading the track progress in one of the labels:
currentTime.text = [NSString stringWithFormat:#"%d:%02d", (int)p.currentTime / 60, (int)p.currentTime % 60];
Here's how I set the total duration of the track in one of the labels:
int seconds = (int)p.duration % 60;
int minutes = (int)p.duration / 60;
duration.text = [NSString stringWithFormat:#"%d:%02d", minutes, seconds];
When I run the app on the device, the track's current time ALWAYS exceeds the duration (by about 5-10 seconds).
Is this a bug in AVAudioPlayer, or am I not doing it correctly?
NOTE: This behavior also occurs on the device (not just on the simulator)
After finding the seconds by using % 60, you should remove those seconds when converting the remaining for the minutes. For e.g., with the total duration of 119 seconds after finding 59 seconds you should remove that from 119 and then do minute conversion for 60 seconds (119-59). That might solve your problem.
Minutes should be float: 152 seconds / 60.0f = 2.5333 not 2.
That being said, if you want to show the remaining minutes without the seconds you already obtain: int minutes = (p.duration-seconds) / 60
Also, for a better method to format time the way you want to, have a look at the second answer in this question (not the accepted solution).
Here is the function:
func setTimeString(duration: Double)->String {
var audioDurationSeconds = duration
var expression = ""
var minutesString = "00"
var minutesFloat = 0.0
if (audioDurationSeconds)/60 >= 1 {
minutesFloat = (audioDurationSeconds) / 60
audioDurationSeconds = TimeInterval(Int(audioDurationSeconds)%60)
if minutesFloat < 10.0 {
minutesString = String.init(format: "0%.f", floor(minutesFloat))
} else {
minutesString = String.init(format: "%.f", floor(minutesFloat))
}
}
if audioDurationSeconds < 10.0 {
expression = String.init(format: "%#:0%i", minutesString, Int(audioDurationSeconds))
} else {
expression = String.init(format: "%#:%i", minutesString, (Int(audioDurationSeconds)))
}
return expression
}
extension UILabel{
func getTimeString(from duration:Double) -> String{
let hours = Int(duration / 3600)
let minutes = Int(duration / 60) % 60
let seconds = Int(duration.truncatingRemainder(dividingBy: 60))
if hours > 0 {
return String(format: "%i:%02i:%02i", arguments: [hours,minutes,seconds])
}else {
return String(format: "%02i:%02i", arguments: [minutes,seconds])
}
}