Swift -整数转换为小时/分钟/秒

我有一个(有点?)关于斯威夫特中的时间转换的基本问题。

我有一个整数,我想转换成小时/分钟/秒。

例子: Int = 27005会给我:

7 Hours  30 Minutes 5 Seconds

我知道如何在PHP中做到这一点,但是,唉,swift不是PHP:-)

关于我如何在swift中实现这一点的任何提示都是非常棒的! 提前谢谢你!< / p >
165170 次浏览

定义

func secondsToHoursMinutesSeconds(_ seconds: Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}

使用

> secondsToHoursMinutesSeconds(27005)
(7,30,5)

let (h,m,s) = secondsToHoursMinutesSeconds(27005)

上面的函数使用Swift元组一次返回三个值。如果需要,可以使用let (var, ...)语法解构元组,或者可以访问单个元组成员。

如果你真的需要用Hours等打印出来,那么使用这样的东西:

func printSecondsToHoursMinutesSeconds(_ seconds: Int) {
let (h, m, s) = secondsToHoursMinutesSeconds(seconds)
print ("\(h) Hours, \(m) Minutes, \(s) Seconds")
}

注意,上面的secondsToHoursMinutesSeconds()实现适用于Int参数。如果你想要一个Double版本,你需要决定返回值是什么——可以是(Int, Int, Double),也可以是(Double, Double, Double)。你可以尝试这样做:

func secondsToHoursMinutesSeconds(seconds: Double) -> (Double, Double, Double) {
let (hr,  minf) = modf(seconds / 3600)
let (min, secf) = modf(60 * minf)
return (hr, min, 60 * secf)
}

以下是一个更结构化/灵活的方法:(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)

使用这样的方法可以添加方便的解析,如下所示:

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

值得注意的是,纯基于整数的方法不考虑闰日/秒。如果用例处理真实的日期/时间,则应该使用日期日历

我已经构建了一个现有答案的mashup,以简化一切并减少斯威夫特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)"
}

用法:

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

打印:

00:01:40

SWIFT 3.0方案基本基于上述方案,并进行了扩展。

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


}
}

用AVPlayer这样调用它?

 let dTotalSeconds = self.player.currentTime()
playingCurrentTime = dTotalSeconds.durationText

下面是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
}

根据GoZoner的答案,我已经写了一个扩展来根据小时,分钟和秒获得时间格式:

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"

我继续并为此创建了一个闭包(在Swift 3中)。

let (m, s) = { (secs: Int) -> (Int, Int) in
return ((secs % 3600) / 60, (secs % 3600) % 60) }(299)

这样m = 4 s = 59。你可以根据自己的喜好来设置格式。如果没有更多的信息,你当然也想增加工作时间。

恕我直言,最简单的方法是:

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)

NSTimeIntervalDouble做扩展。例子:

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

在macOS 10.10+ / iOS 8.0+中引入了(NS)DateComponentsFormatter来创建可读字符串。

它考虑用户的地区和语言。

let interval = 27005


let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute, .second]
formatter.unitsStyle = .full


let formattedString = formatter.string(from: TimeInterval(interval))!
print(formattedString)

可用的单元样式是positionalabbreviatedshortfullspellOutbrief

欲了解更多信息,请阅读documenation

我正在使用这个扩展

 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 ""
}
}

用途不同

// assume myTimeInterval = 96460.397
myTimeInteval.stringFromInterval() // 1d 2h 47m 40s 397ms

斯威夫特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)
}

Vadian的回答的基础上,我写了一个扩展,它接受一个Double(其中TimeInterval是一个类型别名),并输出一个格式化为时间的字符串。

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) ?? ""
}
}

下面是各种DateComponentsFormatter.UnitsStyle选项的样子:

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

以下是我在Swift 4+中使用的音乐播放器。我正在将秒Int转换为可读的字符串格式

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

像这样使用:

print(7903.toAudioString)

输出:2:11:43

颈上的回答不正确。

这是正确的版本

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
}

我回答了对于类似的问题,但是你不需要在结果中显示毫秒。因此,我的解决方案需要iOS 10.0, tvOS 10.0, watchOS 3.0或macOS 10.12。

你应该从我已经在这里提到的答案调用func convertDurationUnitValueToOtherUnits(durationValue:durationUnit:smallestUnitDuration:):

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

@r3dm4n的回答很棒。然而,我也需要一个小时。以防别人也需要,这里是:

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中:

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

调用函数

    timeString(time: TimeInterval(i))

将返回02:44:57

最新代码:XCode 10.4 Swift 5

extension Int {
func timeDisplay() -> String {
return "\(self / 3600):\((self % 3600) / 60):\((self % 3600) % 60)"
}
}
另一种方法是将秒转换为日期,并从日期本身取秒、分和小时。 此解决方案仅限于23:59:59

斯威夫特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)"
}
}

用法:

let seconds : Int = 119
print(seconds.secondsToTime()) // Result = "00:01:59"

Swift 5 &字符串响应,在像样的格式

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

用法:

print(secondsToHoursMinutesSecondsStr(seconds: 20000)) // Result = "5 h 33 min 20 sec"

将数字转换为字符串形式的时间

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

Xcode 12.1。斯威夫特5

DateComponentsFormatter:一个创建字符串表示的格式化程序, 通过使用unitsStyle,你可以得到一个你想要的字符串,并提到allowedUnits。 例如:output for unitsStyle:: for 10000秒

  1. 完整=“2小时46分49秒”;
  2. 位置=“;2:46:40”;
  3. 缩写=“2h 46m 40 &”;
  4. 2小时46分40秒
  5. 短=“2小时46分40秒”;
  6. 简短=“2小时46分40秒”;

使用方便:

 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
}