Swift-시간 / 분 / 초로 정수 변환


131

Swift의 시간 변환에 관한 기본적인 질문이 있습니다.

시간 / 분 / 초로 변환하려는 정수가 있습니다.

예 : Int = 27005 나에게 줄 것이다 :

7 Hours  30 Minutes 5 Seconds

PHP 에서이 작업을 수행하는 방법을 알고 있지만 아쉽게도 swift는 PHP가 아닙니다 :-)

내가 이것을 신속하게 달성 할 수있는 방법에 대한 팁은 환상적입니다! 미리 감사드립니다!

답변:


296

밝히다

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

14
마지막 값 (seconds % 3600) % 60은에 최적화 될 수 있습니다 seconds % 60. 시간을 먼저 추출 할 필요가 없습니다.
zisoft

@GoZoner-printSecondsToHoursMinutesSeconds 함수가 제대로 작동하지 않는 것 같습니다. 이것은 놀이터에서 가지고 있지만 printSecondsToHoursMinutesSeconds는 아무것도 반환하지 않습니다. import UIKit func secondsToHoursMinutesSeconds (초 : Int)-> (Int, Int, Int) {return (seconds / 3600, (seconds 3600) / 60, (seconds) % 3600) % 60)} let (h, m, s) = secondsToHoursMinutesSeconds (27005) func printSecondsToHoursMinutesSeconds (seconds : Int)-> () {let (h, m, s) = 초 ToHoursMinutesSeconds (초) println ( "(h ) 시간, (m) 분, (s) 초 ""}}
Joe

printSecondstoHoursMinutesSeconds()아무것도 반환하지 않습니다 ( -> ()함수 선언 의 반환 유형 참조 ). 이 함수는 무언가를 인쇄합니다. 운동장에 표시되지 않습니다. 무언가를 반환 String하려면 println()호출 을 제거 하고 함수의 반환 유형을 수정하십시오.
GoZoner 2018

@GoZoner-위 구문에서 간단한 질문입니다. 27005를 변수로 어떻게 선언합니까? 나는 발을 신속하게 젖히기 위해 지금 도구를 사용하고 있습니다. 초 (기본 계산 후 생성)를 표시하는 상수가 있습니다. cocSeconds = cocMinutes * 60으로하자. 27005 대신 변수를 배치하기 위해이 코드를 어떻게 조정합니까? 미리 감사드립니다 !!!
Joe

내가 준 솔루션 Int/%기능 의 특성으로 인해 유형에 적합 합니다. 그것은 /진영 부분을 떨어 뜨립니다. 동일한 코드가 작동하지 않습니다 Double. 구체적으로 2 == 13/5이지만 2.6 == 13.0 / 5입니다. 따라서에 대한 다른 구현이 필요합니다 Double. 이에 대한 메모로 답변을 업데이트했습니다.
GoZoner

171

macOS 10.10+에서는 / (NS)DateComponentsFormatter읽을 수있는 문자열을 만들기 위해 iOS 8.0+ 가 도입되었습니다.

사용자의 로캘 및 언어를 고려합니다.

let interval = 27005

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

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

스타일이 가능한 장치 positional, abbreviated, short,full , spellOutbrief.

자세한 내용은 문서 를 참조하십시오 .


19
를 사용 formatter.unitsStyle = .positional하면 내가 원하는 것을 정확하게 제공합니다 ( 7:30:05)! 최고의 답변 IMO
Sam

11
그리고 당신은 제로```formatter.zeroFormattingBehavior = .pad```를 추가 할 수 있습니다
Eduardo Irias

이것의 반대를 얻는 방법. 시간, 분을 초로 변환하는 방법입니다
Angel F Syrus

1
@AngelFSyrus 간단히hours * 3600 + minutes * 60
vadian

59

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

다양한 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

@MaksimKniazev 일반적으로 시간 중심 값은 DoublesSwift 로 표시됩니다 .
Adrian

@Adrian 확장에 감사드립니다. .positional UnitStyle을 좋아하지만 "9"대신 "00:09"로 9 초, "1:25"대신 "01:25"로 1 분 25 초를 표시하고 싶습니다. Double 값을 기반 으로이 계산을 수동으로 수행 할 수 있으며 확장 자체에 통합 할 수있는 방법이 있는지 궁금합니다. 감사합니다.
Vetuka

참고 : 단일 숫자 값 앞에 0을 유지하려면 (또는 단순히 값이 0 인 경우) 이것을 추가해야합니다 formatter.zeroFormattingBehavior = .pad. 3660.asString(style: .positional) // 01:01:00
Moucheg

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

용법:

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


5
내 관점에서 클로저를 추가한다고해서 실제로 아무것도 단순화되지는 않습니다. 폐쇄 할만한 이유가 있습니까?
derpoliuk

@derpoliuk 나는 내 응용 프로그램의 특정 요구에 대한 폐쇄가 필요했습니다
David Seek

24

보다 체계적이고 유연한 접근 방식은 다음과 같습니다. (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

순전히 정수 기반 접근 방식은 윤일 / 초를 고려하지 않습니다. 유스 케이스가 실제 날짜 / 시간을 처리하는 경우 날짜달력을 사용해야합니다.


month구현에 추가해 주 시겠습니까? 미리 감사드립니다!
ixany

3
NSCalendar (Calendar)를 사용해야합니다.
NoLongerContributingToSE

숫자가 10 미만일 때 자동으로 0을 추가 return number < 10 ? "0\(number)" : "\(number)"하는 문자열 포맷터 return String(format: "%02d", number)를 사용하여 대체 할 수 있습니다.
Continuum

19

스위프트 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 초를 반환 합니다


훌륭한! 내가 필요한 것. Int 변수의 9897을 변경하고 원하는 결과를 얻었습니다. 감사합니다!
David_2877

13

스위프트 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)
}

truncatingRemainder는 무엇입니까? Xcode가 나를 인식하지 못합니다.
Alfi

10

다음은 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
}

9

위의 확장 기능을 사용하는 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

8

나는 비슷한 질문에 대답 했다 했지만 결과에 밀리 초를 표시 할 필요는 없습니다. 따라서 내 솔루션에는 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

5

스위프트 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"

3

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"

3

다음은 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


3

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

3

최신 코드 : XCode 10.4 Swift 5

extension Int {
    func timeDisplay() -> String {
        return "\(self / 3600):\((self % 3600) / 60):\((self % 3600) % 60)"
    }
}

2

스위프트 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"

1

가장 간단한 방법 :

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)

int ld대신 double 이 될 수 있습니다 d.
Nik Kov

1

NSTimeInterval이다 Double확장명으로해야합니까. 예:

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

0

나는 이것을 위해 폐쇄를 만들었습니다 (Swift 3에서).

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

이렇게하면 m = 4와 s = 59가됩니다. 원하는대로 형식을 지정할 수 있습니다. 더 자세한 정보는 아니지만 시간을 추가 할 수도 있습니다.


0

스위프트 4이 확장 프로그램을 사용하고 있습니다

 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

0

neek의 답변 이 정확하지 않습니다.

올바른 버전입니다

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
}

0

또 다른 방법은 초를 날짜로 변환하고 구성 요소, 즉 날짜 자체에서 초, 분 및 시간을 가져 오는 것입니다. 이 솔루션은 23:59:59까지만 제한됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.