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

Joe*_*Joe 102 ios swift

关于Swift中的时间转换,我有一个(有点?)基本问题.

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

示例: Int = 27005会给我:

7 Hours  30 Minutes 5 Seconds
Run Code Online (Sandbox Code Playgroud)

我知道如何在PHP中执行此操作,但唉,swift不是PHP :-)

关于如何在swift中实现这一目标的任何提示都太棒了!先感谢您!

GoZ*_*ner 253

限定

func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {
  return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
Run Code Online (Sandbox Code Playgroud)

使用

> secondsToHoursMinutesSeconds(27005)
(7,30,5)
Run Code Online (Sandbox Code Playgroud)

要么

let (h,m,s) = secondsToHoursMinutesSeconds(27005)
Run Code Online (Sandbox Code Playgroud)

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

如果您确实需要Hours使用单词etc 打印出来,请使用以下内容:

func printSecondsToHoursMinutesSeconds (seconds:Int) -> () {
  let (h, m, s) = secondsToHoursMinutesSeconds (seconds)
  print ("\(h) Hours, \(m) Minutes, \(s) Seconds")
}
Run Code Online (Sandbox Code Playgroud)

注意上面的参数实现是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)
}
Run Code Online (Sandbox Code Playgroud)

  • 最后一个值`(秒%3600)%60`可以优化为`seconds%60`.无需先提取小时数. (11认同)

vad*_*ian 142

在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)
Run Code Online (Sandbox Code Playgroud)

可用的单元样式positional,abbreviated,short,full,spellOutbrief.

有关更多信息,请阅读文档.

  • 使用`formatter.unitsStyle = .positional`给出我想要的东西(这是`7:30:05`)!最佳答案IMO (14认同)
  • 这应该是公认的答案. (12认同)
  • 您可以添加零`formatter.zeroFormattingBehavior = .pad``` (8认同)

Adr*_*ian 34

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

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
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是各种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
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考:如果您想在单个数字值之前保留 0(或者只是该值为 0),您需要添加此“formatter.zeroFormattingBehavior = .pad”。这将为我们提供: `3660.asString(style: .positional) // 01:01:00` (6认同)

Dav*_*eek 27

我已经构建了一个现有答案的混搭,以简化一切并减少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)"
}
Run Code Online (Sandbox Code Playgroud)

用法:

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)")                
}
Run Code Online (Sandbox Code Playgroud)

打印:

00:01:40

  • 从我的角度来看,添加闭包并不能简化任何事情.关闭有什么好理由吗? (5认同)

Str*_*ers 18

这是一种更有条理/更灵活的方法:( 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)
Run Code Online (Sandbox Code Playgroud)

有这样的方法允许添加如下的方便解析:

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
Run Code Online (Sandbox Code Playgroud)

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

  • 你应该使用NSCalendar(日历)这样的东西. (3认同)

iOS*_*jas 18

Xcode 12.1。雨燕5

\n

DateComponentsFormatter:创建字符串表示形式的格式化程序,\n通过使用unitsStyle,您可以根据需要获取字符串并提及 allowedUnits。

\n

例如:unitsStyle:: 的输出 10000 秒

\n
    \n
  1. full =“2小时46分49秒”
  2. \n
  3. 位置=“2:46:40”
  4. \n
  5. 缩写=“2h 46m 40s”
  6. \n
  7. pellOut = "两小时四十六分四十秒\xe2\x80\x9d
  8. \n
  9. 短=“2小时46分40秒”
  10. \n
  11. 简短 =“2 小时 46 分 40 秒”
  12. \n
\n

便于使用:

\n
 let time = convertSecondsToHrMinuteSec(seconds: 10000)\n\n\nfunc convertSecondsToHrMinuteSec(seconds:Int) -> String{\n     let formatter = DateComponentsFormatter()\n     formatter.allowedUnits = [.hour, .minute, .second]\n     formatter.unitsStyle = .full\n    \n     let formattedString = formatter.string(from:TimeInterval(seconds))!\n     print(formattedString)\n     return formattedString\n    }\n
Run Code Online (Sandbox Code Playgroud)\n


ZAF*_*007 15

斯威夫特 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)"
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let seconds : Int = 119
print(seconds.secondsToTime()) // Result = "00:01:59"
Run Code Online (Sandbox Code Playgroud)


r3d*_*m4n 12

斯威夫特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)
}
Run Code Online (Sandbox Code Playgroud)


小智 9

这是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
}
Run Code Online (Sandbox Code Playgroud)


Rom*_*mov 7

如果应用程序的目标是iOS 10.0或更高版本,则可以Measurement将秒数转换为小时,分钟和秒。在Swift 4.2.1 / Xcode 10.1中,您可以使用此函数将单位持续时间的值转换为秒:

func convert<MeasurementType: BinaryInteger>(measurementValue: MeasurementType,
                                             unitDuration: UnitDuration) -> (MeasurementType, MeasurementType) {
    let measurementSeconds = Measurement<UnitDuration>(value: Double(measurementValue),
                                                       unit: .seconds)
    let secondsCount = MeasurementType(measurementSeconds.converted(to: unitDuration).value)
    let measurementCurrentUnit = Measurement(value: Double(secondsCount),
                                             unit: unitDuration)
    let currentUnitCount = MeasurementType(measurementCurrentUnit.converted(to: .seconds).value)
    return (secondsCount, measurementValue - currentUnitCount)
}
Run Code Online (Sandbox Code Playgroud)

要获得所需的值,只需调用两次:

func convertSecondsToHoursMinutesSeconds<MeasurementType: BinaryInteger>(seconds: MeasurementType) -> (MeasurementType, MeasurementType, MeasurementType) {
    let hoursAndRestSeconds = convert(measurementValue: seconds, unitDuration: .hours)
    let minutesAndRestSeconds = convert(measurementValue: hoursAndRestSeconds.1, unitDuration: .minutes)
    return (hoursAndRestSeconds.0, minutesAndRestSeconds.0, minutesAndRestSeconds.1)
}
Run Code Online (Sandbox Code Playgroud)

如何使用它:

let result = convertSecondsToHoursMinutesSeconds(seconds: 27005)
print("\(result.0) Hours \(result.1) Minutes \(result.2) Seconds")
Run Code Online (Sandbox Code Playgroud)

如您所见,我在解决方案中没有使用60、3600或其他数字常量。

  • 很酷 我从未见过有人使用此API;) (2认同)

小智 7

在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)
    }
Run Code Online (Sandbox Code Playgroud)

调用功能

    timeString(time: TimeInterval(i))
Run Code Online (Sandbox Code Playgroud)

将返回02:44:57


use*_*232 6

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

  }
}
Run Code Online (Sandbox Code Playgroud)

将它与AVPlayer一起调用就好吗?

 let dTotalSeconds = self.player.currentTime()
 playingCurrentTime = dTotalSeconds.durationText
Run Code Online (Sandbox Code Playgroud)


sc1*_*c13 5

@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)
}
Run Code Online (Sandbox Code Playgroud)


Asa*_*hry 5

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)
 }
Run Code Online (Sandbox Code Playgroud)

用法:

print(secondsToHoursMinutesSecondsStr(seconds: 20000)) // Result = "5 h 33 min 20 sec"
Run Code Online (Sandbox Code Playgroud)