Comment puis-je calculer la différence entre deux dates?

115

Comment puis-je calculer les jours entre le 1er janvier 2010 et (par exemple) le 3 février 2010?

Frederik Heyninck
la source

Réponses:

237
NSDate *date1 = [NSDate dateWithString:@"2010-01-01 00:00:00 +0000"];
NSDate *date2 = [NSDate dateWithString:@"2010-02-03 00:00:00 +0000"];

NSTimeInterval secondsBetween = [date2 timeIntervalSinceDate:date1];

int numberOfDays = secondsBetween / 86400;

NSLog(@"There are %d days in between the two dates.", numberOfDays);

ÉDITER:

N'oubliez pas que les NSDateobjets représentent des moments exacts, ils n'ont aucune information de fuseau horaire associée. Lorsque vous convertissez une chaîne en une date en utilisant par exemple un NSDateFormatter, le NSDateFormatterconvertit l'heure à partir du fuseau horaire configuré. Par conséquent, le nombre de secondes entre deux NSDateobjets sera toujours indépendant du fuseau horaire.

De plus, cette documentation spécifie que l'implémentation du temps par Cocoa ne tient pas compte des secondes intercalaires, donc si vous avez besoin d'une telle précision, vous devrez lancer votre propre implémentation.

dreamlax
la source
5
@RalucaGurau: 86400 est le nombre de secondes dans une journée (soit 60 secondes, fois 60 minutes, fois 24 heures). Cela n'a rien à voir avec le mois.
dreamlax
18
Tous les jours n'ont pas 86400 secondes. Pour un exemple trivial, c'est bien mais ce n'est pas une bonne idée dans le monde réel. Les changements d'heure d'été, les secondes intercalaires, etc. peuvent tout gâcher. NSCalendar peut vous dire combien de secondes il y a dans une journée donnée.
NeilInglis
2
@muthukumar: Pas sur iOS, la méthode n'est disponible que sur Mac OS X. Cette question est balisée cocoaet pas cocoa-touchsi cette réponse ne s'applique qu'à Mac OS X.
dreamlax
1
Le nombre de jours entre deux moments dans le temps sera toujours de 86 400. Que les humains soient sur le point de se tromper pour se réveiller une heure plus tôt que la normale ou non, cela ne change rien au fait qu’une journée dure 86 400 secondes (en ignorant le saut secondes)
dreamlax
1
Je veux juste ajouter que si vous n'avez pas ce +0000 à la fin, vous obtiendrez des dates nulles et une valeur de 0 toujours sur le diff, quoi qu'il arrive. Alors, ne tombez pas dans ce piège.
Volomike
84

Vous pouvez utiliser quelque chose comme ceci:

NSDateComponents *components;
NSInteger days;

components = [[NSCalendar currentCalendar] components: NSDayCalendarUnit 
        fromDate: startDate toDate: endDate options: 0];
days = [components day];

Je crois que cette méthode tient compte de situations telles que les dates qui couvrent un changement d'heure d'été.

Casey Fleser
la source
2
existe-t-il un moyen simple d'ignorer également l'heure pour les dates données?
Mihai Timar
peut être modifié en conséquence pour les autres unités du calendrier :) utilisé pour l'unité Année.
tech savvy
NSDateles objets sont déjà indépendants du fuseau horaire. Les informations de fuseau horaire sont supprimées lors de l'analyse des dates avec par exemple NSDateFormatter, afin que les NSDateobjets représentent des moments exacts dans le temps. Par conséquent, si vous avez déjà startDateet endDate, ces deux objets seront séparés de x secondes. Les fuseaux horaires n'auront rien à voir avec cela.
dreamlax
@Benjamin: Pourquoi dites-vous ça?
dreamlax
dreamlax, votre réponse est fausse. Clair et simple. Calculez le nombre de jours entre midi, heure normale du 1er janvier, et 12h00, heure avancée du 1er avril, et votre formule ne fonctionne pas. Il s'agit d'une formule paresseuse et les développeurs devraient utiliser l'objet NSDateComponents pour calculer cela.
Rickster
25
NSTimeInterval diff = [date2 timeIntervalSinceDate:date1]; // in seconds

date1et date2sont NSDate.

Notez également la définition de NSTimeInterval:

typedef double NSTimeInterval;
Chetan
la source
Notez que NSTimeInterval est vraiment un double, vous pouvez donc l'utiliser comme n'importe quel autre nombre.
Kendall Helmstetter Gelner du
19

Vérifiez ceci. Il prend en charge l'heure d'été, année bissextile, car il utilisait le calendrier iOS pour calculer.Vous pouvez modifier la chaîne et les conditions pour inclure les minutes avec les heures et les jours.

+(NSString*)remaningTime:(NSDate*)startDate endDate:(NSDate*)endDate
{
    NSDateComponents *components;
    NSInteger days;
    NSInteger hour;
    NSInteger minutes;
    NSString *durationString;

    components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: startDate toDate: endDate options: 0];

    days = [components day];
    hour = [components hour];
    minutes = [components minute];

    if(days>0)
    {
        if(days>1)
            durationString=[NSString stringWithFormat:@"%d days",days];
        else
            durationString=[NSString stringWithFormat:@"%d day",days];
        return durationString;
    }
    if(hour>0)
    {        
        if(hour>1)
            durationString=[NSString stringWithFormat:@"%d hours",hour];
        else
            durationString=[NSString stringWithFormat:@"%d hour",hour];
        return durationString;
    }
    if(minutes>0)
    {
        if(minutes>1)
            durationString = [NSString stringWithFormat:@"%d minutes",minutes];
        else
            durationString = [NSString stringWithFormat:@"%d minute",minutes];

        return durationString;
    }
    return @""; 
}
Ankish Jain
la source
cette méthode est le moyen idéal pour calculer le décalage horaire.
Moxarth
juste vous pouvez garder elseif avec toutes ces conditions. sinon vous n'obtiendrez qu'un seul format d'heure affiché.
Moxarth
3

Avec Swift 5 et iOS 12, selon vos besoins, vous pouvez utiliser l'une des deux méthodes suivantes pour trouver la différence entre deux dates en jours.


#1. Utilisation de Calendarla dateComponents(_:from:to:)méthode de

import Foundation

let calendar = Calendar.current

let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!

let dateComponents = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)

print(dateComponents) // prints: day: 1621 isLeapMonth: false
print(String(describing: dateComponents.day)) // prints: Optional(1621)

# 2. Utilisation de DateComponentsFormatterla string(from:to:)méthode de

import Foundation

let calendar = Calendar.current

let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [NSCalendar.Unit.day]

let elapsedTime = formatter.string(from: startDate, to: endDate)
print(String(describing: elapsedTime)) // prints: Optional("1,621 days")
Imanou Petit
la source
1

Swift 4
Essayez ceci et voyez (plage de dates avec chaîne):

// Start & End date string
let startingAt = "01/01/2018"
let endingAt = "08/03/2018"

// Sample date formatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"

// start and end date object from string dates
var startDate = dateFormatter.date(from: startingAt) ?? Date()
let endDate = dateFormatter.date(from: endingAt) ?? Date()


// Actual operational logic
var dateRange: [String] = []
while startDate <= endDate {
    let stringDate = dateFormatter.string(from: startDate)
    startDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate) ?? Date()
    dateRange.append(stringDate)
}

print("Resulting Array - \(dateRange)")

Swift 3

var date1 = Date(string: "2010-01-01 00:00:00 +0000")
var date2 = Date(string: "2010-02-03 00:00:00 +0000")
var secondsBetween: TimeInterval = date2.timeIntervalSince(date1)
var numberOfDays: Int = secondsBetween / 86400
print(numberOfDays)
Krunal
la source
Tous les jours n'ont pas ce nombre de secondes.
Pavan
@Pavan - Vous êtes invités à partager vos contributions en mettant à jour cette réponse et en l'améliorant.
Krunal
Pour l'améliorer, il faudrait que je réécrive toute votre réponse, auquel cas elle peut tout aussi bien être supprimée car ce sera la même solution que la réponse ci-dessus qui n'utilise pas de valeurs codées en dur :)
Pavan
0

Vous pouvez trouver la différence en convertissant la date en secondes et prendre l'intervalle de temps depuis 1970 pour cela, puis vous pouvez trouver la différence entre deux dates.

Himanshu Bhatia
la source
lorsque deux dates peuvent être calculées directement l'une avec l'autre (en supposant le même domaine temporel). Y a-t-il une raison particulière de calculer d'abord les deux dates depuis 1970, puis de trouver la différence?
Adeel
0

Pour trouver la différence, vous devez obtenir la date actuelle et la date future. Dans le cas suivant, j'ai utilisé 2 jours pour un exemple de date future. Calculé par:

2 days* 24 hours* 60 minutes* 60 seconds. Nous prévoyons que le nombre de secondes en 2 jours sera de 172 800.

// Set the current and future date
let now = Date()
let nowPlus2Days = Date(timeInterval: 2*24*60*60, since: now)

// Get the number of seconds between these two dates
let secondsInterval = DateInterval(start: now, end: nowPlus2Days).duration

print(secondsInterval) // 172800.0
Roi Zakai
la source
1
Veuillez ne pas poster uniquement du code comme réponse, mais également expliquer ce que fait votre code et comment il résout le problème de la question. Les réponses avec une explication sont généralement de meilleure qualité et sont plus susceptibles d'attirer des votes positifs.
Mark Rotteveel le