Domanda

Ne ho una quantità di seconds che è passato da un certo evento.È memorizzato in a NSTimeInterval tipo di dati.

Voglio convertirlo in minutes E seconds.

Ad esempio ho:"326.4" secondi e voglio convertirlo nella seguente stringa:"5:26".

Qual è il modo migliore per raggiungere questo obiettivo?

Grazie.

È stato utile?

Soluzione

pseudo-codice:

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

Altri suggerimenti

Breve descrizione

  1. La risposta da Brian Ramsay è più conveniente se desideri solo convertire in minuti.
  2. Se si vuole cacao API farlo per voi e convertire il vostro NSTimeInterval non solo di minuti, ma anche per giorni, mesi, settimane, ecc, ... penso che questo sia un approccio più generico
  3. metodo Usa NSCalendar:

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

    • "I ritorni, come un NSDateComponents oggetto utilizzando componenti specificati, la differenza tra due date in dotazione". Dalla documentazione API.

  4. Crea 2 NSDate la cui differenza è il NSTimeInterval che si desidera convertire. (Se il tuo NSTimeInterval deriva dal confronto tra 2 NSDate non c'è bisogno di fare questo passo, e non è nemmeno necessario il NSTimeInterval).

  5. i tuoi citazioni da NSDateComponents

Codice di esempio

// 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];

Problemi noti

  • Troppo per un semplice conversione, hai ragione, ma è così che le opere API.
  • Il mio suggerimento:. Se ci si abitua a gestire i dati in tempo utilizzando NSDate e NSCalendar, l'API farà il lavoro duro per voi

Tutte queste sembrano più complicata di quanto hanno bisogno di essere! Ecco un modo breve e dolce per convertire un intervallo di tempo in ore, minuti e secondi:

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 quando si mette un galleggiante in un int, si ottiene piano () in modo automatico, ma è possibile aggiungerlo ai primi due, se se ti fa sentire meglio: -)

Perdonami per essere vergine Pila ... Non sono sicuro di come rispondere alla risposta di Brian Ramsay ...

Utilizzando rotondo non funzionerà per il secondo valori compresi tra 59,5 e 59,99,999 mila. Il secondo valore sarà 60 durante questo periodo. Utilizzare trunc invece ...

 double progress;

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

Se ci si rivolge pari o superiore a iOS 8 o OS X 10.10, questo è diventato molto più facile. La nuova classe NSDateComponentsFormatter consente di convertire un dato NSTimeInterval dal suo valore in secondi per una stringa localizzata per mostrare all'utente. Ad esempio:

Objective-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 consente anche per questa uscita sia in forme più lunghi. Maggiori informazioni si possono trovare in di NSHipster articolo NSFormatter . E a seconda di quali classi si sta già lavorando con (se non NSTimeInterval), può essere più conveniente per passare il formattatore un'istanza di NSDateComponents, o di due oggetti NSDate, che può essere fatto anche tramite i seguenti metodi.

Objective-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#>) {
    // ...
}

Il codice di Brian Ramsay, de-pseudofatto:

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

Ecco una versione 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)
}

Può essere utilizzato in questo modo:

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

Uscite:

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

Dal momento che è essenzialmente una doppia ...

Divide da 60,0 ed estrarre la parte integrante e la parte frazionaria.

La parte integrante sarà il numero di minuti.

Moltiplicare la parte frazionaria del 60,0 nuovo.

Il risultato sarà i secondi rimanenti.

Si ricorda che la domanda iniziale è di circa un'uscita stringa, non pseudo-codice o singoli componenti di stringa.

  

voglio convertirlo nella seguente stringa: "05:26"

Molte risposte mancano i problemi di internazionalizzazione, e la maggior parte facendo i calcoli matematici a mano. Tutto solo così 20 ° secolo ...

Non fare la matematica te stesso (Swift 4)

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

05:26


Leverage su librerie

Se si vuole veramente i singoli componenti, e il codice piacevolmente leggibile, controllare SwiftDate :

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

5


@mickmaccallum e @ polarwar per l'utilizzo adeguato di DateComponentsFormatter

Come ho fatto a Swift (compresa la stringa di formattazione per mostrare come "1:23"):

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 2 versione

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"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top