Является ли дата в одну и ту же неделю, месяц, год другой даты в быстрой
Каков наилучший способ узнать, является ли дата на той же неделе (или году или месяце) другой, желательно с расширением и исключительно с использованием Swift?
Например, в Objective-C у меня есть
- (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]);
}
Пожалуйста, не предлагайте решения, связывающие Date
с NSDate
Ответы
Ответ 1
Вы можете использовать метод календаря isDate(equalTo:granularity:)
чтобы проверить его следующим образом:
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()
}
}
Ответ 2
Вы можете использовать это расширение, основанное на коде Objective-C, который вы указали:
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
}
}
Календарь по умолчанию - это autoupdatingCurrent
поэтому, если пользователь изменяет календарь, он будет соответствующим образом обновляться. Также он использует переменные компоненты параметров, которые позволяют вам указать любое количество компонентов, не упаковывая их в массив.
Пример использования:
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
РЕДАКТИРОВАТЬ
Как отметил @Leo Dabus, мы можем использовать здесь set вместо параметров array/variadic - таким образом мы не будем многократно сравнивать одни и те же компоненты, если пользователь передает некоторые дубликаты методу:
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
}
}