En général, si vous voulez garder une trace de " Humain "(c'est-à-dire la date et les heures que vous trouverez sur un calendrier ou une horloge), l'outil que vous voulez est NSDateComponents
, couplé avec NSCalendar
. L'objectif de NSDate
est de garder une trace des moments absolus dans le temps, (*) en termes de secondes depuis un moment de référence, ce qui n'est généralement pas la façon dont les gens pensent du temps. NSDate
devient rapidement incorrecte et souvent contre-productive dès que vous traitez avec des fuseaux horaires, l'heure d'été, ou toute autre chose qui salit la belle cartographie des « secondes écoulées depuis l'époque » et « l'horloge sur le mur. » (*) Mettez de côté la relativité et ce qui ne l'est pas, et supposez que nous pouvons tous être d'accord quand les choses arrivent et que les intervalles de temps peuvent être combinés de façon commutative et transitive dans un univers newtonien simple et agréable. Ignorez également les problèmes comme les secondes intercalaires ou toute autre chose qui pourrait compliquer les choses, et vous avez NSDate
.
Voici une implémentation réelle qui devrait gérer la plupart des bizarreries (comme les temps au-dessus de minuit). Peut ne pas gérer les transitions DST correctement, mais cela devrait vous mettre sur la bonne voie.
let twelveHours: NSTimeInterval = 12 * 60 * 60
func timeLateBetweenDate(actualDate: NSDate, nominalHour: Int, nominalMinute: Int) -> NSTimeInterval {
func timeLateOnDate(onDate: NSDate) -> NSTimeInterval {
let calendar = NSCalendar.currentCalendar()
let expectedDate = calendar.dateBySettingHour(nominalHour, minute: nominalMinute, second: 0, ofDate: onDate, options: [])!
let todayDifference = actualDate.timeIntervalSinceDate(expectedDate)
if todayDifference > twelveHours { // Over 12 hours late; should have checked against tomorrow
return timeLateOnDate(calendar.dateByAddingUnit(.Day, value: 1, toDate: onDate, options: [])!)
} else if todayDifference < -twelveHours { // Over 12 hours early, should have checked against yesterday
return timeLateOnDate(calendar.dateByAddingUnit(.Day, value: -1, toDate: onDate, options: [])!)
}
else {
return todayDifference
}
}
return timeLateOnDate(actualDate)
}
Et dans un peu bâclée ObjC (juste translittération Swift, ce qui serait probablement plus claire comme méthode):
NSTimeInterval twelveHours = 12 * 60 * 60;
NSTimeInterval _timeLateOnDate(NSDate *onDate, NSDate *actualDate, NSUInteger nominalHour, NSUInteger nominalMinute) {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *expectedDate = [calendar dateBySettingHour:nominalHour minute: nominalMinute second: 0 ofDate: onDate options: 0];
NSTimeInterval todayDifference = [actualDate timeIntervalSinceDate:expectedDate];
if (todayDifference > twelveHours) { // Over 12 hours late; should have checked against tomorrow
return _timeLateOnDate([calendar dateByAddingUnit:NSCalendarUnitDay value: 1 toDate: onDate options: 0],
actualDate, nominalHour, nominalMinute);
} else if (todayDifference < -twelveHours) { // Over 12 hours early, should have checked against yesterday
return _timeLateOnDate([calendar dateByAddingUnit:NSCalendarUnitDay value: -1 toDate: onDate options: 0],
actualDate, nominalHour, nominalMinute);
} else {
return todayDifference;
}
}
NSTimeInterval timeLateBetweenDateAndNominalHourMinute(NSDate *actualDate, NSUInteger nominalHour, NSUInteger nominalMinute) {
return _timeLateOnDate(actualDate, actualDate, nominalHour, nominalMinute);
}
La meilleure référence de tutoriel pour votre question est - http://rypress.com/tutorials/objective-c/data-types/dates – user3182143
J'irais avec NSDateComponents, car il n'est pas vraiment connecté au seul point dans le temps une instance NSDate représente. – vikingosegundo