add 0 to hours/minutes under 10 [duplicate] - ios

This question already has answers here:
Leading zeros for Int in Swift
(12 answers)
Closed 6 years ago.
i've some issue to found a proper solution in swift3 to do this :
I have a date like 10h20m. When my hours are under 10 it will be "5h30". I want to out "05h30".
class func getTime(_ user: SUser) -> String {
let currentDate = Date()
let firstDate = user.firstDate
let difference = firstDate?.timeIntervalSince(now)
let hours = String(Int(difference!) / 3600)
let minutes = String(Int(difference!) / 60 % 60)
let time = "\(hours)h\(minutes)m"
return time
}
if someone have an idea how do that simply et properly thank you !

You can do something like this
class func getTime(_ user: SUser) -> String {
let currentDate = Date()
let firstDate = user.firstDate
let difference = firstDate?.timeIntervalSince(now)
let hours = String(Int(difference!) / 3600)
if Int(hours)! < 10 {
hours = "0\(hours)"
}
var minutes = String(Int(difference!) / 60 % 60)
if Int(minutes)! < 10 {
minutes = "0\(minutes)"
}
let time = "\(hours)h\(minutes)m"
return time
}
or a better way
class func getTime(_ user: SUser) -> String {
let currentDate = Date()
let firstDate = user.firstDate
let difference = firstDate?.timeIntervalSince(now)
let hours = Int(difference!) / 3600
let minutes = Int(difference!) / 60 % 60
let time = "\(String(format: "%02d", hours))h\(String(format: "%02d", minutes))m"
return time
}
Suggested here - Leading zeros for Int in Swift

class func getTime(_ user: SUser) -> String {
let currentDate = Date()
let firstDate = user.firstDate
let difference = firstDate?.timeIntervalSince(now)
var hours = String(Int(difference!) / 3600)
if ((Int(difference!) / 3600)<10) {
hours = "0\(hours)"
}
var minutes = String(Int(difference!) / 60 % 60)
if ((Int(difference!) / 60 % 60)<10) {
minutes = "0\(minutes)"
}
let time = "\(hours)h\(minutes)m"
return time
}

I think you would be better off with a simple formatting function that you can call inline.
Try something like
func formatHour(hour:Int) -> String {
return (String(hour).characters.count == 1) ? "0\(hour)" : "\(hour)"
}
let hour = 5
print("\(formatHour(hour: hour))") // output "05"
You can adjust this as needed, maybe pass the string in instead and save doing the conversion in the function. could also add a guard statement to ensure that the number is within the bounds of hours, or a string is less than three characters etc.

Related

Swift - Not enough bits to represent the passed value

Below code works fine on iOS devices and watchOS simulator.
static func getEventDateTime(startDateTime: Date?) -> String {
if let startDateTime = startDateTime {
let startTimeInMillis = Int(startDateTime.timeIntervalSince1970 * 1000)
let fiveMinutesInMillis = 300000
let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval((startTimeInMillis-fiveMinutesInMillis)/1000))
return convertDateToString(eventStartDateTime)
}
return ""
}
However when I run it on Apple Watch Series 3, I get the following error: double value cannot be converted to int because the result would be greater than int.max on line let startTimeInMillis = Int(startDateTime.timeIntervalSince1970 * 1000).
So I changed
let startTimeInMillis = Int(startDateTime.timeIntervalSince1970 * 1000) to let startTimeInMillis = Int64(startDateTime.timeIntervalSince1970 * 1000)
and
let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval((startTimeInMillis-fiveMinutesInMillis)/1000)) to let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval((Int(startTimeInMillis)-fiveMinutesInMillis)/1000)).
Now I am getting following error: Not enough bits to represent the passed value on line let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval((Int(startTimeInMillis)-fiveMinutesInMillis)/1000))
How do I change the function to make it work on Apple Watch Series 3 or watchOS 7?
Updated function code:
static func getEventDateTime(startDateTime: Date?) -> String {
if let startDateTime = startDateTime {
let startTimeInMillis = Int64(startDateTime.timeIntervalSince1970 * 1000)
let fiveMinutesInMillis = 300000
let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval((Int(startTimeInMillis)-fiveMinutesInMillis)/1000))
return convertDateToString(eventStartDateTime)
}
return ""
}
Use the Calendar API to add/subtract time units (doesn't support milliseconds, but does support nanoseconds, which can be converted from): https://developer.apple.com/documentation/foundation/calendar.
func getEventDateTimeCal(startDateTime: Date?) -> String {
if let startDateTime = startDateTime,
let date = Calendar.current.date(byAdding: .minute, value: -5, to: startDateTime) {
return convertDateToString(date, startDateTime)
}
return ""
}
But also, if you don't need millisecond precision, subtract seconds from TimeInterval. Note that TimeInterval is typealias TimeInterval = Double and always represents seconds.
func getEventDateTime(startDateTime: Date?) -> String {
if let startDateTime = startDateTime {
let fiveMinutesInSeconds = 5.0 * 60
let eventStartDateTime = Date(timeIntervalSince1970: startDateTime.timeIntervalSince1970 - fiveMinutesInSeconds)
return convertDateToString(startDateTime, eventStartDateTime)
}
return ""
}

How to Display Best Time in an iOS Game with 3 Significant Digits Decimal Value?

I am saving the best time in my iOS Game using the following functions:-
func format(timeInterval: TimeInterval) -> String {
let interval = Int(timeInterval)
let seconds = interval % 60
let minutes = (interval / 60) % 60
let milliseconds = Int(timeInterval * 1000) % 1000
return String(format: "%02d:%02d.%03d", minutes, seconds, milliseconds)
}
func setBestTime(with time: Int){
let defaults = UserDefaults.standard
let previousBestTime = defaults.integer(forKey: "bestTime")
defaults.set(time > previousBestTime ? time : previousBestTime, forKey: "bestTime")
}
func getBestTime(){
self.bestTimeLabel.text = "\(UserDefaults.standard.integer(forKey: "bestTime"))"
}
func gameOver() {
stopGame()
setBestTime(with: Int(elapsedTime))
}
But, it displays the best time in integer. I want the best time to be displayed in decimal with 3 significant figures. Could anyone please let me know how can I do that? Thanks for the help!
You aren't calling your format function. You simply need to pass the Int value retrieve from UserDefault to format before displaying it on your label.
You should also use UserDefaults.double if you want to store a TimeInterval rather than an Int.
let defaults = UserDefaults.standard
let bestTimeKey = "bestTime"
func format(timeInterval: TimeInterval) -> String {
let interval = Int(timeInterval)
let seconds = interval % 60
let minutes = (interval / 60) % 60
let milliseconds = Int(timeInterval * 1000) % 1000
return String(format: "%02d:%02d.%03d", minutes, seconds, milliseconds)
}
func setBestTime(with time: TimeInterval){
let previousBestTime = defaults.double(forKey: bestTimeKey)
defaults.set(max(time, previousBestTime), forKey: bestTimeKey)
}
func getBestTime() {
let bestTime = defaults.double(forKey: bestTimeKey)
let formattedBestTime = format(timeInterval: bestTime)
bestTimeLabel.text = formattedBestTime
}
func gameOver() {
stopGame()
setBestTime(with: elapsedTime)
}

Format timer label to hours:minutes:seconds in Swift

I have an NSTimer which counts DOWN from 2 hours until 0.
Here are some of my code:
var timer = NSTimer()
let timeInterval:NSTimeInterval = 0.5
let timerEnd:NSTimeInterval = 0.0
var timeCount:NSTimeInterval = 7200.0 // seconds or 2 hours
// TimeString Function
func timeString(time:NSTimeInterval) -> String {
let minutes = Int(time) / 60
let seconds = time - Double(minutes) * 60
let secondsFraction = seconds - Double(Int(seconds))
return String(format:"%02i:%02i.%01i",minutes,Int(seconds),Int(secondsFraction * 10.0))
}
The Timer Label is:
TimerLabel.text = "Time: \(timeString(timeCount))"
HOWEVER, my timer label shows as:
Time: 200:59.0
How do I format my timer label to look like this:
Time: 01:59:59 // (which is hours:minutes:seconds)?
[Please note that I have no problems with my countdown timer, I only need to know how to CHANGE THE TIME FORMAT using the TimeString function.]
EDIT:
Someone mentioned that my question is a possible duplicate of this one: Swift - iOS - Dates and times in different format. HOWEVER, I am asking on how do I change the time format using the TimeString function that I gave above. I am not asking for another WAY on how to do it.
For instance:
let minutes = Int(time) / 60
gives me "200" minutes. etc.
Your calculations are all wrong.
let hours = Int(time) / 3600
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format:"%02i:%02i:%02i", hours, minutes, seconds)
#rmaddy's solution is accurate and answers the question. However, neither the question nor the solution take into account international users. I suggest using DateComponentsFormatter and let the framework handle the calculations and formatting. Doing so makes your code less error prone and more future proof.
I came across this blog post that provides a concise solution:
http://crunchybagel.com/formatting-a-duration-with-nsdatecomponentsformatter/
Pulled from that post, this is the code snippet that would replace the code you're currently using to make your calculations. Updated for Swift 3:
let duration: TimeInterval = 7200.0
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional // Use the appropriate positioning for the current locale
formatter.allowedUnits = [ .hour, .minute, .second ] // Units to display in the formatted string
formatter.zeroFormattingBehavior = [ .pad ] // Pad with zeroes where appropriate for the locale
let formattedDuration = formatter.string(from: duration)
Swift5
var totalSecond = Int()
var timer:Timer?
call startTimer() based on requirement-
func startTimer(){
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(countdown), userInfo: nil, repeats: true)
}
#objc func countdown() {
var hours: Int
var minutes: Int
var seconds: Int
if totalSecond == 0 {
timer?.invalidate()
}
totalSecond = totalSecond - 1
hours = totalSecond / 3600
minutes = (totalSecond % 3600) / 60
seconds = (totalSecond % 3600) % 60
timeLabel.text = String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}
Done
The best way to implement a Timer in Swift (swift 4 works fine).
Declare the variable secs: Int and assign the value, in seconds, of the timer.
Then with the Timer () function, discount one second at a time and pass it to this function.
var secs = 0
var timer = Timer()
func startTimer(segs: Int) {
seg = segs
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerDiscount), userInfo: nil, repeats: true)
}
func timerDiscount() {
let hours = secs / 3600
let mins = secs / 60 % 60
let secs = secs % 60
let restTime = ((hours<10) ? "0" : "") + String(hours) + ":" + ((mins<10) ? "0" : "") + String(mins) + ":" + ((secs<10) ? "0" : "") + String(secs)
}
Declare the variables hours ,minutes and seconds and copy paste the below code it works fine.
if counter > 0 {
let hours = counter / 3600
let minutes = counter / 60
let seconds = counter % 60
counter = counter - 1
timerLbl.text = "\(hours):\(minutes):\(seconds)"
}

Convert Date String to Int Swift

I am trying to convert the string:
let time = "7:30"
to integers:
let hour : Int = 7
let minutes : Int = 30
I am currently looping through the string:
for char in time.characters {
}
But I cannot figure out how to convert a char to an int. Any help would be greatly appreciated.
Answers by #alex_p and #mixel are correct, but it's also possible to do it with Swift split function:
let time = "7:30"
let components = time.characters.split { $0 == ":" } .map { (x) -> Int in return Int(String(x))! }
let hours = components[0]
let minutes = components[1]
Use String.componentsSeparatedByString to split time string to parts:
import Foundation
let time = "7:30"
let timeParts = time.componentsSeparatedByString(":")
if timeParts.count == 2 {
if let hour = Int(timeParts[0]),
let minute = Int(timeParts[1]) {
// use hour and minute
}
}
If you do not want to import Foundation you can split time string to parts with:
let timeParts = time.characters.split(":").map(String.init)
You can split string by : character and then convert results to Int:
let timeStringArray = time.componentsSeparatedByString(":")
if timeStringArray.count == 2 {
hour = timeStringArray[0].toInt
minutes = timeStringArray[1].toInt()
}

Swift - Integer conversion to Hours/Minutes/Seconds

I have a (somewhat?) basic question regarding time conversions in Swift.
I have an integer that I would like converted into Hours / Minutes / Seconds.
Example: Int = 27005 would give me:
7 Hours 30 Minutes 5 Seconds
I know how to do this in PHP, but alas, swift isn't PHP.
Define
func secondsToHoursMinutesSeconds(_ seconds: Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
Use
> secondsToHoursMinutesSeconds(27005)
(7,30,5)
or
let (h,m,s) = secondsToHoursMinutesSeconds(27005)
The above function makes use of Swift tuples to return three values at once. You destructure the tuple using the let (var, ...) syntax or can access individual tuple members, if need be.
If you actually need to print it out with the words Hours etc then use something like this:
func printSecondsToHoursMinutesSeconds(_ seconds: Int) {
let (h, m, s) = secondsToHoursMinutesSeconds(seconds)
print ("\(h) Hours, \(m) Minutes, \(s) Seconds")
}
Note that the above implementation of secondsToHoursMinutesSeconds() works for Int arguments. If you want a Double version you'll need to decide what the return values are - could be (Int, Int, Double) or could be (Double, Double, Double). You could try something like:
func secondsToHoursMinutesSeconds(seconds: Double) -> (Double, Double, Double) {
let (hr, minf) = modf(seconds / 3600)
let (min, secf) = modf(60 * minf)
return (hr, min, 60 * secf)
}
In macOS 10.10+ / iOS 8.0+ (NS)DateComponentsFormatter has been introduced to create a readable string.
It considers the user's locale und language.
let interval = 27005
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
formatter.unitsStyle = .full
let formattedString = formatter.string(from: TimeInterval(interval))!
print(formattedString)
The available unit styles are positional, abbreviated, short, full, spellOut and brief.
For more information please read the documenation.
Building upon Vadian's answer, I wrote an extension that takes a Double (of which TimeInterval is a type alias) and spits out a string formatted as time.
extension Double {
func asString(style: DateComponentsFormatter.UnitsStyle) -> String {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second, .nanosecond]
formatter.unitsStyle = style
return formatter.string(from: self) ?? ""
}
}
Here are what the various DateComponentsFormatter.UnitsStyle options look like:
10000.asString(style: .positional) // 2:46:40
10000.asString(style: .abbreviated) // 2h 46m 40s
10000.asString(style: .short) // 2 hr, 46 min, 40 sec
10000.asString(style: .full) // 2 hours, 46 minutes, 40 seconds
10000.asString(style: .spellOut) // two hours, forty-six minutes, forty seconds
10000.asString(style: .brief) // 2hr 46min 40sec
In Swift 5:
var i = 9897
func timeString(time: TimeInterval) -> String {
let hour = Int(time) / 3600
let minute = Int(time) / 60 % 60
let second = Int(time) % 60
// return formated string
return String(format: "%02i:%02i:%02i", hour, minute, second)
}
To call function
timeString(time: TimeInterval(i))
Will return 02:44:57
I have built a mashup of existing answers to simplify everything and reduce the amount of code needed for Swift 3.
func hmsFrom(seconds: Int, completion: #escaping (_ hours: Int, _ minutes: Int, _ seconds: Int)->()) {
completion(seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
func getStringFrom(seconds: Int) -> String {
return seconds < 10 ? "0\(seconds)" : "\(seconds)"
}
Usage:
var seconds: Int = 100
hmsFrom(seconds: seconds) { hours, minutes, seconds in
let hours = getStringFrom(seconds: hours)
let minutes = getStringFrom(seconds: minutes)
let seconds = getStringFrom(seconds: seconds)
print("\(hours):\(minutes):\(seconds)")
}
Prints:
00:01:40
Here is a more structured/flexible approach: (Swift 3)
struct StopWatch {
var totalSeconds: Int
var years: Int {
return totalSeconds / 31536000
}
var days: Int {
return (totalSeconds % 31536000) / 86400
}
var hours: Int {
return (totalSeconds % 86400) / 3600
}
var minutes: Int {
return (totalSeconds % 3600) / 60
}
var seconds: Int {
return totalSeconds % 60
}
//simplified to what OP wanted
var hoursMinutesAndSeconds: (hours: Int, minutes: Int, seconds: Int) {
return (hours, minutes, seconds)
}
}
let watch = StopWatch(totalSeconds: 27005 + 31536000 + 86400)
print(watch.years) // Prints 1
print(watch.days) // Prints 1
print(watch.hours) // Prints 7
print(watch.minutes) // Prints 30
print(watch.seconds) // Prints 5
print(watch.hoursMinutesAndSeconds) // Prints (7, 30, 5)
Having an approach like this allows the adding of convenience parsing like this:
extension StopWatch {
var simpleTimeString: String {
let hoursText = timeText(from: hours)
let minutesText = timeText(from: minutes)
let secondsText = timeText(from: seconds)
return "\(hoursText):\(minutesText):\(secondsText)"
}
private func timeText(from number: Int) -> String {
return number < 10 ? "0\(number)" : "\(number)"
}
}
print(watch.simpleTimeString) // Prints 07:30:05
It should be noted that purely Integer based approaches don't take leap day/seconds into account. If the use case is dealing with real dates/times Date and Calendar should be used.
Swift 5:
extension Int {
func secondsToTime() -> String {
let (h,m,s) = (self / 3600, (self % 3600) / 60, (self % 3600) % 60)
let h_string = h < 10 ? "0\(h)" : "\(h)"
let m_string = m < 10 ? "0\(m)" : "\(m)"
let s_string = s < 10 ? "0\(s)" : "\(s)"
return "\(h_string):\(m_string):\(s_string)"
}
}
Usage:
let seconds : Int = 119
print(seconds.secondsToTime()) // Result = "00:01:59"
Swift 4
func formatSecondsToString(_ seconds: TimeInterval) -> String {
if seconds.isNaN {
return "00:00"
}
let Min = Int(seconds / 60)
let Sec = Int(seconds.truncatingRemainder(dividingBy: 60))
return String(format: "%02d:%02d", Min, Sec)
}
SWIFT 3.0 solution based roughly on the one above using extensions.
extension CMTime {
var durationText:String {
let totalSeconds = CMTimeGetSeconds(self)
let hours:Int = Int(totalSeconds.truncatingRemainder(dividingBy: 86400) / 3600)
let minutes:Int = Int(totalSeconds.truncatingRemainder(dividingBy: 3600) / 60)
let seconds:Int = Int(totalSeconds.truncatingRemainder(dividingBy: 60))
if hours > 0 {
return String(format: "%i:%02i:%02i", hours, minutes, seconds)
} else {
return String(format: "%02i:%02i", minutes, seconds)
}
}
}
Use it with AVPlayer calling it like this?
let dTotalSeconds = self.player.currentTime()
playingCurrentTime = dTotalSeconds.durationText
Here is another simple implementation in Swift3.
func seconds2Timestamp(intSeconds:Int)->String {
let mins:Int = intSeconds/60
let hours:Int = mins/60
let secs:Int = intSeconds%60
let strTimestamp:String = ((hours<10) ? "0" : "") + String(hours) + ":" + ((mins<10) ? "0" : "") + String(mins) + ":" + ((secs<10) ? "0" : "") + String(secs)
return strTimestamp
}
Xcode 12.1. Swift 5
DateComponentsFormatter: A formatter that creates string representations,
by using unitsStyle u can get a string as you want and mention allowedUnits.
e.g: output for unitsStyle:: for 10000 secods
full = "2 hours, 46 minutes, 49 seconds"
positional = "2:46:40"
abbreviated = "2h 46m 40s"
spellOut = "two hours, forty-six minutes, forty seconds”
short = "2hr,46 min,40 sec"
brief = "2hr 46min 40sec"
Easy to use:
let time = convertSecondsToHrMinuteSec(seconds: 10000)
func convertSecondsToHrMinuteSec(seconds:Int) -> String{
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
formatter.unitsStyle = .full
let formattedString = formatter.string(from:TimeInterval(seconds))!
print(formattedString)
return formattedString
}
I had answered to the similar question, however you don't need to display milliseconds in the result. Hence my solution requires iOS 10.0, tvOS 10.0, watchOS 3.0 or macOS 10.12.
You should call func convertDurationUnitValueToOtherUnits(durationValue:durationUnit:smallestUnitDuration:) from the answer that I already mentioned here:
let secondsToConvert = 27005
let result: [Int] = convertDurationUnitValueToOtherUnits(
durationValue: Double(secondsToConvert),
durationUnit: .seconds,
smallestUnitDuration: .seconds
)
print("\(result[0]) hours, \(result[1]) minutes, \(result[2]) seconds") // 7 hours, 30 minutes, 5 seconds
Answer of #r3dm4n was great. However, I needed also hour in it. Just in case someone else needed too here it is:
func formatSecondsToString(_ seconds: TimeInterval) -> String {
if seconds.isNaN {
return "00:00:00"
}
let sec = Int(seconds.truncatingRemainder(dividingBy: 60))
let min = Int(seconds.truncatingRemainder(dividingBy: 3600) / 60)
let hour = Int(seconds / 3600)
return String(format: "%02d:%02d:%02d", hour, min, sec)
}
Swift 5 & String Response, In presentable format
public static func secondsToHoursMinutesSecondsStr (seconds : Int) -> String {
let (hours, minutes, seconds) = secondsToHoursMinutesSeconds(seconds: seconds);
var str = hours > 0 ? "\(hours) h" : ""
str = minutes > 0 ? str + " \(minutes) min" : str
str = seconds > 0 ? str + " \(seconds) sec" : str
return str
}
public static func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
Usage:
print(secondsToHoursMinutesSecondsStr(seconds: 20000)) // Result = "5 h 33 min 20 sec"
According to GoZoner answer I have wrote an Extension to get the time formatted according to the hours, minute, and seconds:
extension Double {
func secondsToHoursMinutesSeconds () -> (Int?, Int?, Int?) {
let hrs = self / 3600
let mins = (self.truncatingRemainder(dividingBy: 3600)) / 60
let seconds = (self.truncatingRemainder(dividingBy:3600)).truncatingRemainder(dividingBy:60)
return (Int(hrs) > 0 ? Int(hrs) : nil , Int(mins) > 0 ? Int(mins) : nil, Int(seconds) > 0 ? Int(seconds) : nil)
}
func printSecondsToHoursMinutesSeconds () -> String {
let time = self.secondsToHoursMinutesSeconds()
switch time {
case (nil, let x? , let y?):
return "\(x) min \(y) sec"
case (nil, let x?, nil):
return "\(x) min"
case (let x?, nil, nil):
return "\(x) hr"
case (nil, nil, let x?):
return "\(x) sec"
case (let x?, nil, let z?):
return "\(x) hr \(z) sec"
case (let x?, let y?, nil):
return "\(x) hr \(y) min"
case (let x?, let y?, let z?):
return "\(x) hr \(y) min \(z) sec"
default:
return "n/a"
}
}
}
let tmp = 3213123.printSecondsToHoursMinutesSeconds() // "892 hr 32 min 3 sec"
Here is what I use for my Music Player in Swift 4+. I am converting seconds Int to readable String format
extension Int {
var toAudioString: String {
let h = self / 3600
let m = (self % 3600) / 60
let s = (self % 3600) % 60
return h > 0 ? String(format: "%1d:%02d:%02d", h, m, s) : String(format: "%1d:%02d", m, s)
}
}
Use like this:
print(7903.toAudioString)
Output: 2:11:43
Latest Code: XCode 10.4 Swift 5
extension Int {
func timeDisplay() -> String {
return "\(self / 3600):\((self % 3600) / 60):\((self % 3600) % 60)"
}
}
From #Gamec answer
typealias CallDuration = Int
extension CallDuration {
func formatedString() -> String? {
let hours = self / 3600
let minutes = (self / 60) % 60
let seconds = self % 60
if hours > 0 { return String(format: "%0.2d:%0.2d:%0.2d", hours, minutes, seconds) }
return String(format: "%0.2d:%0.2d", minutes, seconds)
}
}
Usage:
let duration: CallDuration = 3000
duration.formatedString() // 50 minute
The simplest way imho:
let hours = time / 3600
let minutes = (time / 60) % 60
let seconds = time % 60
return String(format: "%0.2d:%0.2d:%0.2d", hours, minutes, seconds)
NSTimeInterval is Double do do it with extension. Example:
extension Double {
var formattedTime: String {
var formattedTime = "0:00"
if self > 0 {
let hours = Int(self / 3600)
let minutes = Int(truncatingRemainder(dividingBy: 3600) / 60)
formattedTime = String(hours) + ":" + (minutes < 10 ? "0" + String(minutes) : String(minutes))
}
return formattedTime
}
}
convert a number into time as a string
func convertToHMS(number: Int) -> String {
let hour = number / 3600;
let minute = (number % 3600) / 60;
let second = (number % 3600) % 60 ;
var h = String(hour);
var m = String(minute);
var s = String(second);
if h.count == 1{
h = "0\(hour)";
}
if m.count == 1{
m = "0\(minute)";
}
if s.count == 1{
s = "0\(second)";
}
return "\(h):\(m):\(s)"
}
print(convertToHMS(number:3900))
I went ahead and created a closure for this (in Swift 3).
let (m, s) = { (secs: Int) -> (Int, Int) in
return ((secs % 3600) / 60, (secs % 3600) % 60) }(299)
This will give m = 4 and s = 59. So you can format that as you wish. You may of course want to add hours as well, if not more information.
Swift 4 I'm using this extension
extension Double {
func stringFromInterval() -> String {
let timeInterval = Int(self)
let millisecondsInt = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
let secondsInt = timeInterval % 60
let minutesInt = (timeInterval / 60) % 60
let hoursInt = (timeInterval / 3600) % 24
let daysInt = timeInterval / 86400
let milliseconds = "\(millisecondsInt)ms"
let seconds = "\(secondsInt)s" + " " + milliseconds
let minutes = "\(minutesInt)m" + " " + seconds
let hours = "\(hoursInt)h" + " " + minutes
let days = "\(daysInt)d" + " " + hours
if daysInt > 0 { return days }
if hoursInt > 0 { return hours }
if minutesInt > 0 { return minutes }
if secondsInt > 0 { return seconds }
if millisecondsInt > 0 { return milliseconds }
return ""
}
}
useage
// assume myTimeInterval = 96460.397
myTimeInteval.stringFromInterval() // 1d 2h 47m 40s 397ms
neek's answer isn't correct.
here's the correct version
func seconds2Timestamp(intSeconds:Int)->String {
let mins:Int = (intSeconds/60)%60
let hours:Int = intSeconds/3600
let secs:Int = intSeconds%60
let strTimestamp:String = ((hours<10) ? "0" : "") + String(hours) + ":" + ((mins<10) ? "0" : "") + String(mins) + ":" + ((secs<10) ? "0" : "") + String(secs)
return strTimestamp
}
Another way would be convert seconds to date and take the components i.e seconds, minutes and hour from date itself.
This solution has limitation only till 23:59:59

Resources