Definiować
func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
Posługiwać się
> secondsToHoursMinutesSeconds(27005)
(7,30,5)
lub
let (h,m,s) = secondsToHoursMinutesSeconds(27005)
Powyższa funkcja wykorzystuje krotki Swift do zwracania trzech wartości jednocześnie. Niszczysz krotkę za pomocą let (var, ...)
składni lub w razie potrzeby możesz uzyskać dostęp do poszczególnych członków krotki.
Jeśli naprawdę chcesz wydrukować go ze słowami Hours
itp., Użyj czegoś takiego:
func printSecondsToHoursMinutesSeconds (seconds:Int) -> () {
let (h, m, s) = secondsToHoursMinutesSeconds (seconds)
print ("\(h) Hours, \(m) Minutes, \(s) Seconds")
}
Zauważ, że powyższa implementacja secondsToHoursMinutesSeconds()
działa dla Int
argumentów. Jeśli chcesz mieć Double
wersję, musisz zdecydować, jakie są zwracane wartości - mogą być (Int, Int, Double)
lub mogą być (Double, Double, Double)
. Możesz spróbować czegoś takiego:
func secondsToHoursMinutesSeconds (seconds : Double) -> (Double, Double, Double) {
let (hr, minf) = modf (seconds / 3600)
let (min, secf) = modf (60 * minf)
return (hr, min, 60 * secf)
}
(seconds % 3600) % 60
może zostać zoptymalizowana doseconds % 60
. Nie ma potrzeby wcześniejszego wyodrębniania godzin.printSecondstoHoursMinutesSeconds()
nic nie zwraca (patrz-> ()
typ zwracany w deklaracji funkcji). Funkcja wypisuje coś; który nie pojawia się na placu zabaw. Jeśli chcesz, aby coś zwróciło, powiedz a, aString
następnie usuńprintln()
wywołanie i popraw typ zwracania funkcji.Int
typów ze względu na charakter funkcji/
i%
. To oznacza,/
że część frakcyjna spada. Ten sam kod nie będzie działaćDouble
. W szczególności 2 == 13/5 ale 2,6 == 13,0 / 5. Dlatego potrzebowałbyś innej implementacjiDouble
. Zaktualizowałem moją odpowiedź uwagą na ten temat.W macOS 10.10+ / iOS 8.0+
(NS)DateComponentsFormatter
wprowadzono tworzenie czytelnego ciągu.Uwzględnia ustawienia regionalne i język użytkownika.
let interval = 27005 let formatter = DateComponentsFormatter() formatter.allowedUnits = [.hour, .minute, .second] formatter.unitsStyle = .full let formattedString = formatter.string(from: TimeInterval(interval))! print(formattedString)
Dostępne są jednostkowe style
positional
,abbreviated
,short
,full
,spellOut
ibrief
.Aby uzyskać więcej informacji, przeczytaj dokumentację .
źródło
formatter.unitsStyle = .positional
daje dokładnie to, czego chcę (czyli7:30:05
)! Najlepsza odpowiedź IMOhours * 3600 + minutes * 60
Opierając się na odpowiedzi Vadiana , napisałem rozszerzenie, które pobiera
Double
(któregoTimeInterval
jest aliasem typu) i wypluwa ciąg sformatowany jako czas.extension Double { func asString(style: DateComponentsFormatter.UnitsStyle) -> String { let formatter = DateComponentsFormatter() formatter.allowedUnits = [.hour, .minute, .second, .nanosecond] formatter.unitsStyle = style guard let formattedString = formatter.string(from: self) else { return "" } return formattedString } }
Oto,
DateComponentsFormatter.UnitsStyle
jak wyglądają różne opcje: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
źródło
Doubles
Swift.formatter.zeroFormattingBehavior = .pad
. To dałoby nam:3660.asString(style: .positional) // 01:01:00
Stworzyłem połączenie istniejących odpowiedzi, aby uprościć wszystko i zmniejszyć ilość kodu potrzebnego do 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)" }
Stosowanie:
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)") }
Wydruki:
00:01:40
źródło
Oto bardziej ustrukturyzowane / elastyczne podejście: (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)
Takie podejście umożliwia dodanie wygodnej analizy w następujący sposób:
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
Należy zauważyć, że podejścia oparte wyłącznie na liczbach całkowitych nie uwzględniają dnia / sekund przestępnych. Jeśli przypadek użycia dotyczy rzeczywistych dat / godzin, należy użyć daty i kalendarza .
źródło
month
do swojej realizacji? Z góry dziękuję!return number < 10 ? "0\(number)" : "\(number)"
, używając programu formatującego ciąg,return String(format: "%02d", number)
który automatycznie dodaje zero, gdy liczba jest mniejsza niż 10W 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) }
Aby wywołać funkcję
timeString(time: TimeInterval(i))
Powróci 02:44:57
źródło
Szybki 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) }
źródło
Oto kolejna prosta implementacja w 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 }
źródło
Rozwiązanie SWIFT 3.0 oparte w przybliżeniu na powyższym z rozszerzeniami.
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) } } }
Użyć go z AVPlayerem nazywającym to w ten sposób?
let dTotalSeconds = self.player.currentTime() playingCurrentTime = dTotalSeconds.durationText
źródło
Odpowiedziałem na podobne pytanie , ale nie musisz wyświetlać milisekund w wyniku. Dlatego moje rozwiązanie wymaga systemu iOS 10.0, tvOS 10.0, watchOS 3.0 lub macOS 10.12.
Powinieneś zadzwonić
func convertDurationUnitValueToOtherUnits(durationValue:durationUnit:smallestUnitDuration:)
z odpowiedzi, o której już tutaj wspomniałem: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
źródło
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)" } }
Stosowanie:
let seconds : Int = 119 print(seconds.secondsToTime()) // Result = "00:01:59"
źródło
Zgodnie z odpowiedzią GoZonera napisałem rozszerzenie, aby uzyskać formatowanie czasu według godzin, minut i sekund:
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"
źródło
Oto, czego używam w moim odtwarzaczu muzycznym w Swift 4+. Konwertuję Int sekund na czytelny format String
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) } }
Użyj w ten sposób:
print(7903.toAudioString)
Wynik:
2:11:43
źródło
Odpowiedź @ r3dm4n była świetna. Jednak potrzebowałem też godziny. Na wypadek, gdyby ktoś inny też potrzebował tutaj, jest:
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) }
źródło
Najnowszy kod: XCode 10.4 Swift 5
extension Int { func timeDisplay() -> String { return "\(self / 3600):\((self % 3600) / 60):\((self % 3600) % 60)" } }
źródło
Szybka odpowiedź 5 i ciągów, w reprezentacyjnym formacie
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) }
Stosowanie:
print(secondsToHoursMinutesSecondsStr(seconds: 20000)) // Result = "5 h 33 min 20 sec"
źródło
Najprostszy sposób 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)
źródło
ld
double zamiastd
for int.NSTimeInterval
toDouble
zrobić to z rozszerzeniem. Przykład: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 } }
źródło
Poszedłem do przodu i stworzyłem dla tego zamknięcie (w Swift 3).
let (m, s) = { (secs: Int) -> (Int, Int) in return ((secs % 3600) / 60, (secs % 3600) % 60) }(299)
To da m = 4 i s = 59. Możesz więc sformatować to, jak chcesz. Możesz oczywiście dodać godziny, jeśli nie więcej informacji.
źródło
Swift 4 Używam tego rozszerzenia
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 "" } }
użytkowanie
// assume myTimeInterval = 96460.397 myTimeInteval.stringFromInterval() // 1d 2h 47m 40s 397ms
źródło
odpowiedź neeka jest nieprawidłowa.
oto poprawna wersja
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 }
źródło
Innym sposobem byłoby przeliczenie sekund na datę i pobranie składników, tj. Sekund, minut i godzin od samej daty. To rozwiązanie ma ograniczenia tylko do 23:59:59
źródło
zamień liczbę na czas jako ciąg
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))
źródło