Pregunta

Tengo una cantidad de seconds que pasa de un determinado evento. Se almacena en un tipo de datos NSTimeInterval.

Quiero convertirlo en minutes y seconds.

Por ejemplo tengo: "326,4" segundos y quiero convertirla en la siguiente cadena: "5:26".

¿Cuál es la mejor manera de lograr este objetivo?

Gracias.

¿Fue útil?

Solución

pseudo-código:

minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)

Otros consejos

Breve descripción

  1. La respuesta de Brian Ramsay es más conveniente si sólo desea convertir en minutos.
  2. Si desea API Cocoa que lo haga por usted y convertir su NSTimeInterval no sólo a minutos sino también a días, meses, semanas, etc, ... Creo que este es un enfoque más genérico
  3. Método de Uso NSCalendar:

    • (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts

    • "devoluciones, como un NSDateComponents objeto utilizando componentes especificados, la diferencia entre dos fechas suministrados". A partir de la documentación de la API.

  4. Crea 2 NSDate cuya diferencia es la NSTimeInterval desea convertir. (Si su NSTimeInterval proviene de la comparación de 2 NSDate que no es necesario realizar este paso, y usted ni siquiera necesita el NSTimeInterval).

  5. Obtener sus citas de NSDateComponents

Código de ejemplo

// The time interval 
NSTimeInterval theTimeInterval = 326.4;

// Get the system calendar
NSCalendar *sysCalendar = [NSCalendar currentCalendar];

// Create the NSDates
NSDate *date1 = [[NSDate alloc] init];
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:theTimeInterval sinceDate:date1]; 

// Get conversion to months, days, hours, minutes
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit;

NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:date1  toDate:date2  options:0];

NSLog(@"Conversion: %dmin %dhours %ddays %dmoths",[conversionInfo minute], [conversionInfo hour], [conversionInfo day], [conversionInfo month]);

[date1 release];
[date2 release];

Problemas conocidos

  • Demasiado para esta conversión, tiene usted razón, pero eso es cómo funciona el API.
  • Mi sugerencia:. Si uno se acostumbra a gestionar los datos de tiempo utilizando NSDate y NSCalendar, la API va a hacer el trabajo duro para usted

Todos los éstos parecen más complicadas de lo que necesitan para estar! Esta es una forma corta y dulce para convertir un intervalo de tiempo en horas, minutos y segundos:

NSTimeInterval timeInterval = 326.4;
long seconds = lroundf(timeInterval); // Since modulo operator (%) below needs int or long

int hour = seconds / 3600;
int mins = (seconds % 3600) / 60;
int secs = seconds % 60;

Nota cuando se pone un flotador en un int, se obtiene piso () de forma automática, pero se puede añadir a los dos primeros si, si te hace sentir mejor: -)

Perdóname por ser virgen Pila ... No estoy seguro de cómo responder a la respuesta de Brian Ramsay ...

Uso ronda no funcionará para segundos valores entre 59,5 y 59.99999. El segundo valor será 60 durante este período. Trunc utilizar en su lugar ...

 double progress;

 int minutes = floor(progress/60);
 int seconds = trunc(progress - minutes * 60);

Si usted está apuntando en o por encima de iOS 8 o OS X 10.10, esto es ahora mucho más fácil. La nueva clase NSDateComponentsFormatter le permite convertir un NSTimeInterval dado respecto a su valor en segundos a una cadena localizada para mostrar al usuario. Por ejemplo:

Objetivo-C

NSTimeInterval interval = 326.4;

NSDateComponentsFormatter *componentFormatter = [[NSDateComponentsFormatter alloc] init];

componentFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
componentFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropAll;

NSString *formattedString = [componentFormatter stringFromTimeInterval:interval];
NSLog(@"%@",formattedString); // 5:26

Swift

let interval = 326.4

let componentFormatter = NSDateComponentsFormatter()

componentFormatter.unitsStyle = .Positional
componentFormatter.zeroFormattingBehavior = .DropAll

if let formattedString = componentFormatter.stringFromTimeInterval(interval) {
    print(formattedString) // 5:26
}

NSDateCompnentsFormatter también permite para esta salida para estar en formas más largas. Más información se puede encontrar en la NSHipster artículo NSFormatter . Y dependiendo de qué clases ya está trabajando con (si no NSTimeInterval), puede ser más conveniente para pasar el formateador una instancia de NSDateComponents, o dos objetos NSDate, lo que se puede hacer así a través de los métodos siguientes.

Objetivo-C

NSString *formattedString = [componentFormatter stringFromDate:<#(NSDate *)#> toDate:<#(NSDate *)#>];
NSString *formattedString = [componentFormatter stringFromDateComponents:<#(NSDateComponents *)#>];

Swift

if let formattedString = componentFormatter.stringFromDate(<#T##startDate: NSDate##NSDate#>, toDate: <#T##NSDate#>) {
    // ...
}

if let formattedString = componentFormatter.stringFromDateComponents(<#T##components: NSDateComponents##NSDateComponents#>) {
    // ...
}
código

de Brian Ramsay, pseudofied-DE:

- (NSString*)formattedStringForDuration:(NSTimeInterval)duration
{
    NSInteger minutes = floor(duration/60);
    NSInteger seconds = round(duration - minutes * 60);
    return [NSString stringWithFormat:@"%d:%02d", minutes, seconds];
}

Aquí hay una versión Swift:

func durationsBySecond(seconds s: Int) -> (days:Int,hours:Int,minutes:Int,seconds:Int) {
    return (s / (24 * 3600),(s % (24 * 3600)) / 3600, s % 3600 / 60, s % 60)
}

Puede ser utilizado como esto:

let (d,h,m,s) = durationsBySecond(seconds: duration)
println("time left: \(d) days \(h) hours \(m) minutes \(s) seconds")
    NSDate *timeLater = [NSDate dateWithTimeIntervalSinceNow:60*90];

    NSTimeInterval duration = [timeLater  timeIntervalSinceNow];

    NSInteger hours = floor(duration/(60*60));
    NSInteger minutes = floor((duration/60) - hours * 60);
    NSInteger seconds = floor(duration - (minutes * 60) - (hours * 60 * 60));

    NSLog(@"timeLater: %@", [dateFormatter stringFromDate:timeLater]);

    NSLog(@"time left: %d hours %d minutes  %d seconds", hours,minutes,seconds);

Salidas:

timeLater: 22:27
timeLeft: 1 hours 29 minutes  59 seconds

Ya que es esencialmente un doble ...

Dividir por 60.0 y extraer la parte integral y la parte fraccionaria.

La parte integral será el número total de minutos.

Multiplicar la parte fraccionaria por 60,0 de nuevo.

El resultado será los segundos restantes.

Recuerde que la pregunta original se trata de una salida de cadena, no pseudo-código o componentes individuales de cuerda.

  

Quiero convertirlo en la siguiente cadena: "05:26"

Muchas de las respuestas no disponen de las cuestiones de internacionalización, y la mayoría de hacer los cálculos matemáticos con la mano. Todo el siglo 20 tan ...

No hacer lo mismo matemáticas (Swift 4)

let timeInterval: TimeInterval = 326.4
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.unitsStyle = .positional
if let formatted = dateComponentsFormatter.string(from: timeInterval) {
    print(formatted)
}
  

05:26


Las reglas del juego en las bibliotecas

Si realmente quieres componentes individuales, y el código legible gratamente, echa un vistazo a SwiftDate :

import SwiftDate
...
if let minutes = Int(timeInterval).seconds.in(.minute) {
    print("\(minutes)")
}
  

5


@mickmaccallum y @ polarwar para el uso adecuado de DateComponentsFormatter

¿Cómo lo hice en Swift (incluyendo el formato de cadenas para mostrar como "uno y veintitrés"):

let totalSeconds: Double = someTimeInterval
let minutes = Int(floor(totalSeconds / 60))
let seconds = Int(round(totalSeconds % 60))        
let timeString = String(format: "%02d:%02d", minutes, seconds)
NSLog(timeString)

Swift versión 2

extension NSTimeInterval {
            func toMM_SS() -> String {
                let interval = self
                let componentFormatter = NSDateComponentsFormatter()

                componentFormatter.unitsStyle = .Positional
                componentFormatter.zeroFormattingBehavior = .Pad
                componentFormatter.allowedUnits = [.Minute, .Second]
                return componentFormatter.stringFromTimeInterval(interval) ?? ""
            }
        }
    let duration = 326.4.toMM_SS()
    print(duration)    //"5:26"
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top