2015-01-22 4 views
11

Sto utilizzando NSDateComponentsFormatter su iOS 8 e ho notato un possibile errore nell'implementazione del metodo stringFromTimeInterval:, ma non posso dirlo con certezza.NSDateComponentsFormatter stringFromTimeInterval restituisce una stringa errata per intervalli inferiori a 1 minuto

Ecco come ho creato il formattatore:

NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init]; 
formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDefault; 
formatter.allowedUnits = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 
formatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional; 

Ora quando mi passa niente di meno di 60 secondi per il metodo stringFromTimeInterval:, i rendimenti formattatore sia 1 o 01, che è ovviamente sbagliato, dovrebbe restituire qualcosa come 0:XX.

Quello che ho notato è che cambiando il unitsStyle in qualsiasi cosa tranne NSDateComponentsFormatterUnitsStylePositional il metodo restituisce una stringa corretta!

Esempio:

Con unitsStyle = NSDateComponentsFormatterUnitsStylePositional:

(lldb) po [formatter stringFromTimeInterval:12] 
= "1" 

=> Dovrebbe restituire "00:12" !!

Con unitsStyle = NSDateComponentsFormatterUnitsStyleAbbreviated:

(lldb) po [formatter stringFromTimeInterval:12] 
= "12 s" 

=> Corretta!

Questo mi permette di pensare che si tratti di un bug nell'implementazione dell'API di Apple o mi sto perdendo qualcosa?

+0

Controlla la mia risposta/aggira in basso ... – MiKL

+0

So che non è la soluzione, ma puoi semplicemente impostare il valore della stringa float da timeInterval se è inferiore a 60: if (self.timeInterval <60) { stringFromInterval = [NSString stringWithFormat: @ "% 2.0f", self.timeInterval]; } Avete in mente di chiedere nei forum degli sviluppatori Apple? – xarly

risposta

1

NSDateComponentsFormatterZeroFormattingBehaviorDefault significa eliminare gli zeri iniziali e altri zeri per lo stile delle unità posizionali.

ad es. con i valori consentitiUnits nel codice, il risultato [formatter stringFromTimeInterval: 120] è "2:00" invece di "0d 0:02:00", poiché l'oggetto formattatore ha rimosso tutti i valori zero iniziali.

Se si desidera riservare i posti valore zero, è possibile utilizzare NSDateComponentsFormatterZeroFormattingBehaviorNone

Per il motivo per cui [stringFromTimeInterval formattatore: 12] risultato è 1, penso oggetto formattatore trova "12" da sola è ambiguo in quanto non ha finale valori o indicatori per significato come in "1d" per esempio.

9

Questo sembra essere ancora un problema con iOS 8.3 e Xcode 6.3. Tuttavia, c'è un modo per ovviare a questo problema, che, se non perfetto, consente almeno di ottenere una formattazione corretta senza dover gestire autonomamente i componenti rilevanti per la suddivisione del tempo.

Ecco un esempio soluzione a Swift (che è possibile testare in un parco giochi)

let formatter = NSDateComponentsFormatter() 
formatter.unitsStyle = .Positional 
formatter.zeroFormattingBehavior = .Pad 
formatter.allowedUnits = .CalendarUnitMinute | .CalendarUnitSecond 

Calling let string = formatter.stringFromTimeInterval(4) stamperà "00:04".

La chiamata let string = formatter.stringFromTimeInterval(88) stampa "01:28".

Ora puoi giocare con lo allowedUnits a seconda che tu abbia più di 1 ora o 1 giorno.Ad esempio, in una classe che ha una proprietà formatter:

func updateTimeFormatterForTime(time: NSTimeInterval) { 
    if time > 3600 && time < 24 * 3600 { 
     self.formatter.allowedUnits = .CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond 
    } else if time > 24 * 3600 { 
     self.formatter.allowedUnits = .CalendarUnitDay | .CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond 
    } 
} 
+0

.CalendarUnitMinute e .CalendarUnitHour, questi non esistono più in 9.1 Non penso o forse non l'hanno mai fatto o non so dove trovarli. Non posso assegnarli a AllowedUnits per qualche motivo e non fanno parte di NSDateComponentsFormatter, almeno non più. –

+0

'.CalendarUnitMinute' et al sono ora' .Minute' ecc. Non sono stati rimossi. – squarefrog

0

Che ne dite di questa funzione:

func stringFromTimeInterval(interval: NSTimeInterval) -> String { 
    let ti: Int = Int(interval) 
    let seconds: Int = ti % 60 
    let minutes: Int = (ti/60) % 60 
    let hours: Int = (ti/3600) 
    var time: String? = nil 
    if hours > 0 { 
     time = String(format: "%02i:%02i:%02i", hours, minutes, seconds) 
    } 
    else { 
     time = String(format: "%02i:%02i", minutes, seconds) 
    } 
    return time! 
} 

tempo ritorni in questa stringa formattata: 59:04 (mm: ss) o 9:01: 34 (hh: mm: ss)

Problemi correlati