web-dev-qa-db-ja.com

NSTimeIntervalからswiftの時、分、秒、ミリ秒への変換

私のコードはここにあります:

func stringFromTimeInterval(interval:NSTimeInterval) -> NSString {

    var ti = NSInteger(interval)
    var ms = ti * 1000
    var seconds = ti % 60
    var minutes = (ti / 60) % 60
    var hours = (ti / 3600)

      return NSString(format: "%0.2d:%0.2d:%0.2d",hours,minutes,seconds,ms)
}

出力では、ミリ秒の結果が間違っています。ミリ秒を正しく見つける方法を考えてください。

46
Lydia

Swiftは浮動小数点数の剰余計算をサポートしているため、% 1を使用できます。

var ms = Int((interval % 1) * 1000)

次のように:

func stringFromTimeInterval(interval: TimeInterval) -> NSString {

  let ti = NSInteger(interval)

  let ms = Int((interval % 1) * 1000)

  let seconds = ti % 60
  let minutes = (ti / 60) % 60
  let hours = (ti / 3600)

  return NSString(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)
}

結果:

stringFromTimeInterval(12345.67)                   "03:25:45.670"

スウィフト4:

extension TimeInterval{

        func stringFromTimeInterval() -> String {

            let time = NSInteger(self)

            let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
            let seconds = time % 60
            let minutes = (time / 60) % 60
            let hours = (time / 3600)

            return String(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)

        }
    }

つかいます:

self.timeLabel.text = player.duration.stringFromTimeInterval()
110
Matthias Bauch

Swift 3拡張

この方法は、各ピースがどこから来たのかを簡単に確認できるので、ニーズに合わせてより簡単に変更できると思います

extension TimeInterval {
    private var milliseconds: Int {
        return Int((truncatingRemainder(dividingBy: 1)) * 1000)
    } 

    private var seconds: Int {
        return Int(self) % 60
    } 

    private var minutes: Int {
        return (Int(self) / 60 ) % 60
    } 

    private var hours: Int {
        return Int(self) / 3600
    } 

    var stringTime: String {
        if hours != 0 {
            return "\(hours)h \(minutes)m \(seconds)s"
        } else if minutes != 0 {
            return "\(minutes)m \(seconds)s"
        } else if milliseconds != 0 {
            return "\(seconds)s \(milliseconds)ms"
        } else {
            return "\(seconds)s"
        }
    }
}
24
Jake Cronin

@ matthias-bauch回答に基づいて、Objective-Cで同等。

+ (NSString *)stringFromTimeInterval:(NSTimeInterval)timeInterval
{
    NSInteger interval = timeInterval;
    NSInteger ms = (fmod(timeInterval, 1) * 1000);
    long seconds = interval % 60;
    long minutes = (interval / 60) % 60;
    long hours = (interval / 3600);

    return [NSString stringWithFormat:@"%0.2ld:%0.2ld:%0.2ld,%0.3ld", hours, minutes, seconds, (long)ms];
}
16
Minos

IOS 8以降、macOS 10.10以降用のSwift 3ソリューション(時間のゼロパディングが重要でない場合):

func stringFromTime(interval: TimeInterval) -> String {
    let ms = Int(interval.truncatingRemainder(dividingBy: 1) * 1000)
    let formatter = DateComponentsFormatter()
    formatter.allowedUnits = [.hour, .minute, .second]
    return formatter.string(from: interval)! + ".\(ms)"
}

print(stringFromTime(interval: 12345.67)) // "3:25:45.670"
11
vadian

スウィフト4:

extension TimeInterval{

        func stringFromTimeInterval() -> String {

            let time = NSInteger(self)

            let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
            let seconds = time % 60
            let minutes = (time / 60) % 60
            let hours = (time / 3600)

            return String(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)

        }
    }

つかいます:

self.timeLabel.text = player.duration.stringFromTimeInterval()
9

.remainder(間違った値を返す)を使用しないSwift 4:

func stringFromTimeInterval(interval: Double) -> NSString {

    let hours = (Int(interval) / 3600)
    let minutes = Int(interval / 60) - Int(hours * 60)
    let seconds = Int(interval) - (Int(interval / 60) * 60)

    return NSString(format: "%0.2d:%0.2d:%0.2d",hours,minutes,seconds)
}
7
mirap

これらの回答のほとんどは時代遅れだと思います。時間間隔を表す文字列を表示する場合は、パディングとローカリゼーションを処理するため、常にDateComponentsFormatterを使用する必要があります。

5
lilpit

Swift 2.0で時間と分を秒に変換する場合:

///RETORNA TOTAL DE SEGUNDOS DE HORA:MINUTOS
func horasMinutosToSeconds (HoraMinutos:String) -> Int {

    let formatar = NSDateFormatter()
    let calendar = NSCalendar.currentCalendar()
    formatar.locale = NSLocale.currentLocale()
    formatar.dateFormat = "HH:mm"

    let Inicio = formatar.dateFromString(HoraMinutos)
    let comp = calendar.components([NSCalendarUnit.Hour, NSCalendarUnit.Minute], fromDate: Inicio!)

    let hora = comp.hour
    let minute = comp.minute

    let hours = hora*3600
    let minuts = minute*60

    let totseconds = hours+minuts

    return totseconds
}
4
Pablo Ruan

Swift 4(範囲チェックあり〜クラッシュなし)

import Foundation

extension TimeInterval {

var stringValue: String {
    guard self > 0 && self < Double.infinity else {
        return "unknown"
    }
    let time = NSInteger(self)

    let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
    let seconds = time % 60
    let minutes = (time / 60) % 60
    let hours = (time / 3600)

    return String(format: "%0.2d:%0.2d:%0.2d.%0.3d", hours, minutes, seconds, ms)

}
}
3
maslovsa

Swift 3バージョンの@hixFieldの回答、現在は日数があり、以前の日付を処理しています:

extension TimeInterval {
    func timeIntervalAsString(_ format : String = "dd days, hh hours, mm minutes, ss seconds, sss ms") -> String {
        var asInt   = NSInteger(self)
        let ago = (asInt < 0)
        if (ago) {
            asInt = -asInt
        }
        let ms = Int(self.truncatingRemainder(dividingBy: 1) * (ago ? -1000 : 1000))
        let s = asInt % 60
        let m = (asInt / 60) % 60
        let h = ((asInt / 3600))%24
        let d = (asInt / 86400)

        var value = format
        value = value.replacingOccurrences(of: "hh", with: String(format: "%0.2d", h))
        value = value.replacingOccurrences(of: "mm",  with: String(format: "%0.2d", m))
        value = value.replacingOccurrences(of: "sss", with: String(format: "%0.3d", ms))
        value = value.replacingOccurrences(of: "ss",  with: String(format: "%0.2d", s))
        value = value.replacingOccurrences(of: "dd",  with: String(format: "%d", d))
        if (ago) {
            value += " ago"
        }
        return value
    }

}
2
Ohad Cohen

Swift 4 Extension-ナノ秒精度

import Foundation

extension TimeInterval {

    func toReadableString() -> String {

        // Nanoseconds
        let ns = Int((self.truncatingRemainder(dividingBy: 1)) * 1000000000) % 1000
        // Microseconds
        let us = Int((self.truncatingRemainder(dividingBy: 1)) * 1000000) % 1000
        // Milliseconds
        let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
        // Seconds
        let s = Int(self) % 60
        // Minutes
        let mn = (Int(self) / 60) % 60
        // Hours
        let hr = (Int(self) / 3600)

        var readableStr = ""
        if hr != 0 {
            readableStr += String(format: "%0.2dhr ", hr)
        }
        if mn != 0 {
            readableStr += String(format: "%0.2dmn ", mn)
        }
        if s != 0 {
            readableStr += String(format: "%0.2ds ", s)
        }
        if ms != 0 {
            readableStr += String(format: "%0.3dms ", ms)
        }
        if us != 0 {
            readableStr += String(format: "%0.3dus ", us)
        }
        if ns != 0 {
            readableStr += String(format: "%0.3dns", ns)
        }

        return readableStr
    }
}
1
Mick

Swift 2拡張子+変数形式に変換されます:

extension NSTimeInterval {

    func timeIntervalAsString(format format : String = "hh:mm:ss:sss") -> String {
        let ms      = Int((self % 1) * 1000)
        let asInt   = NSInteger(self)
        let s = asInt % 60
        let m = (asInt / 60) % 60
        let h = (asInt / 3600)

        var value = format
        value = value.replace("hh",  replacement: String(format: "%0.2d", h))
        value = value.replace("mm",  replacement: String(format: "%0.2d", m))
        value = value.replace("sss", replacement: String(format: "%0.3d", ms))
        value = value.replace("ss",  replacement: String(format: "%0.2d", s))
        return value
    }

}

extension String {
    /**
     Replaces all occurances from string with replacement
     */
    public func replace(string:String, replacement:String) -> String {
        return self.stringByReplacingOccurrencesOfString(string, withString: replacement, options: NSStringCompareOptions.LiteralSearch, range: nil)
    }

}
0
HixField

Precision入力パラメーターを使用した@maslovsaのわずかに改善されたバージョンを次に示します。

import Foundation

extension TimeInterval {

    enum Precision {
        case hours, minutes, seconds, milliseconds
    }

    func toString(precision: Precision) -> String? {
        guard self > 0 && self < Double.infinity else {
            assertionFailure("wrong value")
            return nil
        }

        let time = NSInteger(self)

        let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
        let seconds = time % 60
        let minutes = (time / 60) % 60
        let hours = (time / 3600)

        switch precision {
        case .hours:
            return String(format: "%0.2d", hours)
        case .minutes:
            return String(format: "%0.2d:%0.2d", hours, minutes)
        case .seconds:
            return String(format: "%0.2d:%0.2d:%0.2d", hours, minutes, seconds)
        case .milliseconds:
            return String(format: "%0.2d:%0.2d:%0.2d.%0.3d", hours, minutes, seconds, ms)
        }
    }
}

および使用法:

let time: TimeInterval = (60 * 60 * 8) + 60 * 24.18
let hours = time.toString(precision: .hours) // 08
let minutes = time.toString(precision: .minutes) // 08:24
let seconds = time.toString(precision: .seconds) // 08:24:10
let milliseconds = time.toString(precision: .milliseconds) // 08:24:10.799