Question

J'ai une quantité de seconds qui est passé d'un certain événement. Il est stocké dans un type de données NSTimeInterval.

Je veux le convertir en minutes et seconds.

Par exemple, j'ai: « 326,4 » secondes et je veux le convertir dans la chaîne suivante: "5:26".

Quelle est la meilleure façon d'atteindre cet objectif?

Merci.

Était-ce utile?

La solution

pseudo-code:

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

Autres conseils

Brève description

  1. La réponse de Brian Ramsay est plus pratique si vous voulez seulement convertir en minutes.
  2. Si vous voulez API Cocoa faire pour vous et convertir votre NSTimeInterval non seulement à quelques minutes, mais aussi à quelques jours, mois, semaine, etc ... Je pense que cela est une approche plus générique
  3. Utiliser la méthode NSCalendar:

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

    • « retour, comme un NSDateComponents objet en utilisant des composants spécifiques, la différence entre deux dates fournies ». A partir de la documentation de l'API.

  4. Créer 2 NSDate dont la différence est la NSTimeInterval que vous voulez convertir. (Si votre NSTimeInterval vient de comparer 2 NSDate vous n'avez pas besoin de faire cette étape, et vous n'avez même pas besoin du NSTimeInterval).

  5. Obtenez vos citations de NSDateComponents

Exemple de code

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

Problèmes connus

  • Trop juste pour une conversion, vous avez raison, mais c'est le fonctionnement de l'API.
  • Ma suggestion:. Si vous êtes habitué à gérer vos données de temps en utilisant NSDate et NSCalendar, l'API fera le travail pour vous

Tous ces look plus compliquées qu'elles doivent être! Voici un moyen court et doux pour convertir un intervalle de temps en heures, minutes et secondes:

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;

Remarque lorsque vous mettez un flotteur dans un int, vous obtenez étage () automatiquement, mais vous pouvez l'ajouter aux deux premiers si si vous fait sentir mieux: -)

Pardonnez-moi d'être une vierge Stack ... Je ne sais pas comment répondre à la réponse de Brian Ramsay ...

L'utilisation ronde ne fonctionnera pas pour la deuxième valeur entre 59,5 et 59,99999. La deuxième valeur sera 60 au cours de cette période. Utilisez trunc à la place ...

 double progress;

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

Si vous ciblez ou au-dessus iOS 8 ou OS X 10,10, c'est devenu beaucoup plus facile. La nouvelle classe NSDateComponentsFormatter vous permet de convertir un NSTimeInterval donné de sa valeur en quelques secondes à une chaîne localisée pour montrer à l'utilisateur. Par exemple:

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 permet également de cette sortie soit sous des formes plus longues. Plus d'informations peuvent être trouvées dans NSFormatter article de NSHipster. Et en fonction de ce que les classes que vous travaillez déjà avec (sinon NSTimeInterval), il peut être plus commode de passer le formatter une instance de NSDateComponents ou deux objets NSDate, qui peut être fait aussi bien par les méthodes suivantes.

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

Brian code de Ramsay, de-pseudofied:

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

Voici une version 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)
}

Peut être utilisé comme ceci:

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

Sorties:

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

Comme il est essentiellement un double ...

Diviser par 60,0 et extraire la partie entière et la partie fractionnaire.

La partie intégrale sera le nombre entier de minutes.

Multiplier la fraction de 60,0 à nouveau.

Le résultat sera les secondes restantes.

Rappelez-vous que la question initiale est sur une sortie de chaîne, pas pseudo-code ou des composants de chaîne individuels.

  

Je veux convertir dans la chaîne suivante: « 05:26 »

De nombreuses réponses manquent les questions d'internationalisation, et la plupart faisant les calculs mathématiques à la main. Tout juste si 20ème siècle ...

Ne pas faire le calcul vous-même (Swift 4)

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

05:26


Effet de levier sur les bibliothèques

Si vous voulez vraiment des composants individuels, et le code agréable à lire, consultez SwiftDate :

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

5


Crédits @mickmaccallum et @ polarwar pour une utilisation adéquate des DateComponentsFormatter

Comment je l'ai fait à Swift (y compris la chaîne mise en forme pour le montrer comme « 01: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 version 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"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top