2011-02-08 31 views
69

Si tengo un NSTimeInterval que está configurado para decir 200.0, ¿hay alguna manera de convertir eso en 00:03:20, estaba pensando que podría inicializar un NSDate con él y luego usar NSDateFormatter usando HH: mm: ss. Mi pregunta es, ¿hay una forma rápida de hacerlo o tengo que dividir el número yo mismo y usar [NSString stringWithFormat: %02d:%02d:%02d, myHour, myMin, mySec]?NSTimeInterval a HH: mm: ss?

Respuesta

187

No es necesario utilizar NSDateFormatter ni nada que no sea división y módulo. NSTimeInterval es solo un doble que contiene segundos.

Swift

func stringFromTimeInterval(interval: NSTimeInterval) -> String { 
    let interval = Int(interval) 
    let seconds = interval % 60 
    let minutes = (interval/60) % 60 
    let hours = (interval/3600) 
    return String(format: "%02d:%02d:%02d", hours, minutes, seconds) 
} 

Objective-C

- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval { 
    NSInteger ti = (NSInteger)interval; 
    NSInteger seconds = ti % 60; 
    NSInteger minutes = (ti/60) % 60; 
    NSInteger hours = (ti/3600); 
    return [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes, (long)seconds]; 
} 
+0

muy apreciada, eso es lo que estaba pensando, pero yo sólo quería comprobar que no estaba perdiendo algo ya incluidos como parte del iOS SDK. – fuzzygoat

+0

que tú. Me salvó un dolor de cabeza. – Robert

+0

Quiero señalar que ":" funciona como un delimitador solo en inglés y en algunos otros idiomas. Finlandés, por ejemplo, usa "." - como este "15.02.59" – sgosha

10

Algunas líneas adicionales de código, pero me siento utilizando NSDateComponents dará un valor más preciso.

- (NSString *)getTimeRepresentationFromDate:(NSDate *)iDate withTimeInterval:(NSTimeInterval)iTimeInterval { 
    NSString *aReturnValue = nil; 
    NSDate *aNewDate = [iDate dateByAddingTimeInterval:iTimeInterval]; 

    unsigned int theUnits = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit; 
    NSCalendar *aCalender = [NSCalendar currentCalendar]; 
    NSDateComponents *aDateComponents = [aCalender components:theUnits fromDate:iDate toDate:aNewDate options:0]; 

    aReturnValue = [NSString stringWithFormat:@"%d:%d:%d", [aDateComponents hour], [aDateComponents minute], [aDateComponents second]]; 

    return aReturnValue; 
} 
+0

El método anterior usa las 2 fechas con las cuales se crea TimeInterval. También puede pasar [NSDate date] al parámetro iDate como valor predeterminado. – Roshit

+2

¿De qué manera es esto "más preciso" que el método utilizado por @ matthias-bauch? –

+1

con este método obtienes un intervalo de tiempo en segundos, horas, min. En términos de 60 mientras que la respuesta de @ matthias-bauch te da en términos decimales, por ejemplo si esperas suficiente tiempo verás 1 min 79 seg en vez de 2 min 19 seg –

5
NSTimeInterval ti = 3667; 
double hours = floor(ti/60/60); 
double minutes = floor((ti - (hours * 60 * 60))/60); 
double seconds = floor(ti - (hours * 60 * 60) - (minutes * 60)); 
83

En iOS 8, utilice NSDateComponentsFormatter.

NSDateComponentsFormatter *dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; 
NSLog(@"%@", [dateComponentsFormatter stringFromTimeInterval:200.0]); 

outputs "3:20".

NSDateComponentsFormatter *dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init]; 
dateComponentsFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad; 
dateComponentsFormatter.allowedUnits = (NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond); 
NSLog(@"%@", [dateComponentsFormatter stringFromTimeInterval:200.0]); 

salidas "0:03:20".

+2

Nice update. Pero si realmente se trata de un cálculo tan simple, ¿no estaría utilizando estos objetos una gran sobrecarga (siempre que no haya un formato dinámico involucrado)? –

+0

necesita el formato para asegurarse de que la cadena aparece correctamente para las diferentes configuraciones regionales, etc. –

+0

Comentario realmente minúsculo, pero es extraño dar un ejemplo de la función C para la pregunta de ObjectiveC. ¿Vale la pena cambiarlo al formato ObjectiveC? – Rilakkuma

4

para "extender" la sugerencia de Matthias Bauch, en Swift Me gustaría hacer de esto una propiedad calculada de NSTimeInterval:

extension NSTimeInterval { 
    var stringValue: String { 
    let interval = Int(self) 
    let seconds = interval % 60 
    let minutes = (interval/60) % 60 
    let hours = (interval/3600) 
    return String(format: "%02d:%02d:%02d", hours, minutes, seconds) 
    } 
} 

La ventaja de esto es que está asociado con el tipo NSTimeInterval, no su controlador de vista o cualquier otro lugar pones esa función. Para utilizar usted iría algo como:

let timeInterval = NSDate().timeIntervalSinceDate(start)   
self.elapsedTimeLabel.text = timeInterval.stringValue 
+0

¡Gracias, Kenny! En mi caso los necesitaba por separado, así que agregué variables adicionales a su extensión: "var seconds: Int {let interval = Int (self); let seconds = interval% 60; return seconds}" y así sucesivamente durante minutos y horas. Entonces ese uso será: print ("minutes spent: \ (timeInterval.minutes)") – Vitalii

5

En Swift 2, iOS 8+.Esto se asegura de que sólo muestran horas cuando sea necesario

func format(duration: NSTimeInterval) -> String { 
    let formatter = NSDateComponentsFormatter() 
    formatter.zeroFormattingBehavior = .Pad 

    if duration >= 3600 { 
    formatter.allowedUnits = [.Hour, .Minute, .Second] 
    } else { 
    formatter.allowedUnits = [.Minute, .Second] 
    } 

    return formatter.stringFromTimeInterval(duration) ?? "" 
} 

Así que tienen

print(format(12)) // 0:12 
print(format(65)) // 1:05 
print(format(1750)) // 29:10 
print(format(3890)) // 1:04:50 
print(format(45720)) // 12:42:00 
11

Swift versión 3 de respuesta onmyway133 's:

import Foundation 

func format(_ duration: TimeInterval) -> String { 
    let formatter = DateComponentsFormatter() 
    formatter.zeroFormattingBehavior = .pad 
    formatter.allowedUnits = [.minute, .second] 

    if duration >= 3600 { 
     formatter.allowedUnits.insert(.hour) 
    } 

    return formatter.string(from: duration)! 
} 


print(format(12)) // 0:12 
print(format(65)) // 1:05 
print(format(1750)) // 29:10 
print(format(3890)) // 1:04:50 
print(format(45720)) // 12:42:00 
+0

¿Está creando un DateComponentsFormatter costoso en cuanto a rendimiento, como un DateFormatter o NumberFormatter? – Moshe

0

Sobre la base de la respuesta de @ onmyway133 aquí está la versión de Swift 4:

func format(duration: TimeInterval) -> String { 
    let formatter = DateComponentsFormatter() 
    formatter.zeroFormattingBehavior = .pad 

    if duration >= 3600 { 
     formatter.allowedUnits = [.hour, .minute, .second]; 
    } else { 
     formatter.allowedUnits = [.minute, .second]; 
    } 

    return formatter.string(from: duration) ?? ""; 
} 
0

directamente de documentos de manzana: en el archivo h:

@property(strong,nonatomic)NSDateComponentsFormatter *timerFormatter; 

en m archivo

@synthesize timerFormatter; 

- (void)viewDidLoad { 
[super viewDidLoad]; 
NSDateComponentsFormatter *timerFormatter = [[NSDateComponentsFormatter alloc] init]; 
timerFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional; 
//10:59 Positional THIS ONE DOES NOT SEEM TO WORK iOS<9 WHEN <1Minute JUST SHOWS 01, 10m 59s Abbreviated, 10min 59sec Short, 10minutes 59seconds Full ... 
timerFormatter.allowedUnits = NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond; 
} 

dondequiera que usted necesita para convertir su NSTimeInterval timeInterval a hh: mm: cadena ss, hacer esto :

NSString *txt=[timerFormatter stringFromTimeInterval:timeInterval]; 
0

Supongo que la fracción del temporizador debe ser superada. Como código de Matthias estaba creando ese tema en cuestión de segundos, me utilizar los siguientes ligeramente modificado respecto a las Matthias

- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval { 
     int ti = (int) ceil(interval); 
     int seconds = ti % 60; 
     int minutes = (ti/60) % 60; 
     int hours = (ti/3600); 
     return [NSString stringWithFormat:@"%02d:%02d:%02d",hours, minutes, seconds]; 
    } 
Cuestiones relacionadas