Convert dates to multiple formats with SwiftDate - swift

Is it possible to convert a date, say it is in minutes to another format using SwiftDate library? For example:
77 minutes = 1 hour, 17 minutes

Why not to use this library? You can import NSDateTimeAgo.bundle and NSDate+Extension.swift. And to convert your timestamp to lets say 1 hour, 17 minutes you can do like this:
let timestamp = //timestamp or time
let date = Date(timeIntervalSince1970: timestamp!)
let timeAgo = date.timeAgo
print(timeAgo)
I am suggesting you this because it is more lightweight. And if you do not need the "ago" then you can remove those from NSDateTimeAgo.string file.
But you can also do it without any library like this eg with seconds:
func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
func secondsToHoursMinutesSeconds (seconds:Int) -> () {
let (h, m, s) = secondsToHoursMinutesSeconds (seconds: seconds)
print ("\(h) Hours, \(m) Minutes, \(s) Seconds")
}
secondsToHoursMinutesSeconds(seconds: 3000)// it would print 0 Hours, 50 Minutes, 0 Seconds
You can also suit it for your needs(this code is from this answer).

Related

MInutes and seconds with 2 digits

I have an input in seconds I store it in a var:
var totalTime = 60
I want to show it with 2 digits for minutes and 2 digits for seconds:
01:00
What I have tried:
let minutes = String(totalTime / 60)
let seconds = String(totalTime % 60)
label.text = minutes + ":" + seconds
This gives me: 1:0
But I want 01:00
I tried and It does not work:
label.text = String(format: "%02d:%02d", minutes, seconds)
The problem with your second approach is that it expects an integer and you are passing a string.
let minutes = totalTime / 60
let seconds = totalTime % 60
label.text = String(format: "%02d:%02d", minutes, seconds)

Get 12h hours am/pm Time

I want to display the time from a Slider to a Label. So i must convert the value and get the current day time on it like 00:00 am/pm.
So i need there a stepper how print all 5 steps like (5,10,15,20,25....50,55)
So this code on the bottom don´t run good, have anybody a better way to make that ?
I have try it but it becomes an error when i slider back (zb: when it´s 8:00 am and i slider back to 7:55 am it come for first 7:00 am.
Here is the code:
func valueChange(_ sender: CircleSlider) {
let countmin = Int(Double(sender.value) * 14.4)
var hour = countmin / 60
let mins = countmin - (hour*60)
if hour >= 12 {
hour -= 12
Am.text = "Pm"
} else {
Am.text = "Am"
}
hours = hour
let i = String(mins)
switch i {
case "Nil":
minutes = 00
case "0":
minutes = 00
case "5":
minutes = 05
case "10":
minutes = 10
case "15":
minutes = 15
case "25":
minutes = 25
case "30":
minutes = 30
case "35":
minutes = 35
case "40":
minutes = 40
case "45":
minutes = 45
case "50":
minutes = 50
case "55":
minutes = 55
case "60":
minutes = 60
default:
break
}
self.circleTime.text = "\(String(format: "%02d", hours!)):\(String(format: "%02d", minutes!))"
}
Thank´s for Help :)
I think there's an issue in your method for 7:56, 7:57, 7:58, 7:59 (it is not truncating well). This code should work for you:
func valueChange(_ sender: CircleSlider) {
let countmin = Int(Double(sender.value) * 14.4)
var hour = countmin / 60
let mins = countmin - (hour * 60)
if hour >= 12 {
hour -= 12
Am = "Pm"
} else {
Am = "Am"
}
hours = hour
minutes = roundToFives(Double(mins))
// This fixes when you have hh:60. For instance, it fixes 7:60 to 8:00
if minutes == 60 {
hours = hour + 1
minutes = 0
}
self.circleTime.text = "\(String(format: "%02d", hours!)):\(String(format: "%02d", minutes!))"
}
// idea of this method comes from: http://stackoverflow.com/questions/27922406/round-double-to-closest-10-swift
private func roundToFives(x : Double) -> Int {
return 5 * Int(round(x / 5.0))
}

Convert decimal to hours:minutes:seconds

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.

How can I format numbers in order to have always two digits?

I am creating a countdown timer that shows hours:minutes:seconds.
The function I have works however, it returns the values as 1 digit if the number is less than 10. (ex. 2:3:15)
How can I format my function in order to have always two digits?
I am looking for a result like: 02:03:15
func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
Alternatively using DateComponentsFormatter
lazy var dateComponentsFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.zeroFormattingBehavior = .pad
formatter.allowedUnits = [.hour, .minute, .second]
return formatter
}()
func secondsToHoursMinutesSeconds(seconds: Int) -> String {
let hourPad = seconds < 36000 ? "0" : "" // add 0 in front if less than 10 hours
return hourPad + dateComponentsFormatter.string(from: seconds)!
}
secondsToHoursMinutesSeconds(3602) // 01:00:02
Since DateComponentsFormatter does not pad the hours automatically with zeroFormattingBehavior = .pad, you have to add that "manually".
The formatter itself is declared as a lazy computed property to avoid repetitive re-instantiation.

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])
}
}