Quelle est la meilleure façon de savoir si une date est dans la même semaine (ou année ou mois) qu'une autre, de préférence avec une extension, et en utilisant uniquement Swift?
Par exemple, dans Objective-C, j'ai
- (BOOL)isSameWeekAs:(NSDate *)date {
NSDateComponents *otherDay = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:self];
NSDateComponents *today = [[NSCalendar currentCalendar] components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
return ([today weekOfYear] == [otherDay weekOfYear] &&
[today year] == [otherDay year] &&
[today era] == [otherDay era]);
}
Veuillez ne pas proposer de solutions reliant Date
à NSDate
Vous pouvez utiliser la méthode de calendrier isDate(equalTo:granularity:)
pour le vérifier comme suit:
extension Date {
func isInSameWeek(date: Date) -> Bool {
return Calendar.current.isDate(self, equalTo: date, toGranularity: .weekOfYear)
}
func isInSameMonth(date: Date) -> Bool {
return Calendar.current.isDate(self, equalTo: date, toGranularity: .month)
}
func isInSameYear(date: Date) -> Bool {
return Calendar.current.isDate(self, equalTo: date, toGranularity: .year)
}
func isInSameDay(date: Date) -> Bool {
return Calendar.current.isDate(self, equalTo: date, toGranularity: .day)
}
var isInThisWeek: Bool {
return isInSameWeek(date: Date())
}
var isInYesterday: Bool {
return Calendar.current.isDateInYesterday(self)
}
var isInToday: Bool {
return Calendar.current.isDateInToday(self)
}
var isInTomorrow: Bool {
return Calendar.current.isDateInTomorrow(self)
}
var isInTheFuture: Bool {
return Date() < self
}
var isInThePast: Bool {
return self < Date()
}
}
Vous pouvez utiliser cette extension basée sur le code Objective-C que vous avez fourni:
extension Date {
func hasSame(_ components: Calendar.Component..., as date: Date, using calendar: Calendar = .autoupdatingCurrent) -> Bool {
return components.filter { calendar.component($0, from: date) != calendar.component($0, from: self) }.isEmpty
}
}
Le calendrier par défaut ici est le autoupdatingCurrent
donc si l'utilisateur modifie le calendrier, il sera mis à jour en conséquence. Il utilise également des composants de paramètres variadiques qui vous permettent de spécifier n'importe quel nombre de composants sans les encapsuler dans un tableau.
Exemple d'utilisation:
let date1 = Date()
let date2 = Date()
let date3 = Date(timeIntervalSince1970: 30.0)
print(date1.hasSame(.weekOfYear, .day, .hour, as: date2)) // true
print(date1.hasSame(.weekOfYear, as: date3)) // false
ÉDITER
Comme l'a souligné @Leo Dabus, nous pouvons utiliser set here au lieu de paramètres de tableau/variadic - de cette façon, nous éviterons de comparer les mêmes composants plusieurs fois si l'utilisateur transmet des doublons à la méthode:
extension Date {
func hasSame(_ components: Set<Calendar.Component>, as date: Date, using calendar: Calendar = .autoupdatingCurrent) -> Bool {
return components.filter { calendar.component($0, from: date) != calendar.component($0, from: self) }.isEmpty
}
}