conversion de NSTimeInterval en heures, minutes, secondes, millisecondes dans swift

Mon code est ici:

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

en sortie les millisecondes donnent un mauvais résultat.Donnez s'il vous plaît une idée comment trouver millisecondes correctement.

31
demandé sur Lydia 2015-03-05 10:39:58

12 réponses

Swift prend en charge les calculs du reste sur les nombres à virgule flottante, nous pouvons donc utiliser % 1.

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

comme dans:

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

résultat:

stringFromTimeInterval(12345.67)                   "03:25:45.670"
79
répondu Matthias Bauch 2016-12-03 07:48:28

extension SWIFT 3

je pense que de cette façon est plus facile de voir où chaque pièce vient de sorte que vous pouvez plus facilement le modifier selon vos besoins

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"
        }
    }
}
17
répondu Jake Cronin 2017-11-28 10:19:30

équivalent en Objectif-C, basé sur la réponse de @matthias-bauch.

+ (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
répondu Minos 2015-10-01 09:37:06

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

        }
    }

Utilisation:

self.timeLabel.text = player.duration.stringFromTimeInterval()
7
répondu RaziPour1993 2018-09-21 07:35:05

solution Swift 3 pour iOS 8+, macOS 10.10+ si le Zero-padding des heures n'a pas d'importance:

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"
6
répondu vadian 2017-07-04 16:22:43

Swift 4, sans utiliser le .remainder (qui renvoie des valeurs erronées):

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)
}
5
répondu mirap 2017-11-19 16:06:47

pour convertir l'heure et les minutes en secondes dans 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
}
3
répondu Pablo Ruan 2016-03-05 15:42:28

je pense que la plupart de ces réponses sont périmées, vous devriez toujours utiliser DateComponentsFormatter si vous voulez afficher une chaîne représentant un intervalle de temps, parce qu'il va gérer le remplissage et la localisation pour vous.

3
répondu lilpit 2018-06-27 15:50:57

version swift 3 de la réponse de @hixField, maintenant avec les jours et le traitement des dates précédentes:

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
répondu Ohad Cohen 2016-12-25 15:30:56

converti en une extension swift 2 + Format variable:

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
répondu HixField 2016-09-24 10:39:52

Swift 4 Extension-avec une précision de nanosecondes

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
    }
}
0
répondu Mick 2018-09-20 03:06:28

Swift 4 (avec vérification de Plage ~ sans se bloque)

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)

}
}
0
répondu maslovsa 2018-09-24 10:57:36