Is a date in same week, month, year of another date in swift

What is the best way to know if a date is in the same week (or year or month) as another, preferably with an extension, and solely using Swift?

As an example, in Objective-C I have

  • App Store - Managing Availability of Your Apps' Previous Versions
  • libcurl linker error on Xcode5 but working fine on Xcode 4.6
  • What exactly does a nib file look like if you were to look inside?
  • App Store - Best way to merge a paid and free version into a free version with IAP
  • Can not launch the app on device
  • What is the difference between Int and Int32 in Swift?
  • - (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]);
    }
    

    Please don’t propose solutions bridging Date to NSDate

    2 Solutions Collect From Internet About “Is a date in same week, month, year of another date in swift”

    You can use calendar method isDate(equalTo:granularity:) to check it as follow:

    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 isInToday: Bool {
            return Calendar.current.isDateInToday(self)
        }
        var isInTheFuture: Bool {
            return Date() < self
        }
        var isInThePast: Bool {
            return self < Date()
        }
    }
    

    You can use this extension that is based on the Objective-C code you’ve provided:

    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
        }
    }
    

    The default calendar here is the autoupdatingCurrent so if user changes the calendar it will update accordingly. Also it uses variadic parameter components that allows you to specify any number of components without wrapping them into an array.

    Example of usage:

    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
    

    EDIT

    As @Leo Dabus pointed out we may use set here instead of array/variadic parameters – that way we’ll avoid comparing the same components many times if user passes some duplicates to the method:

    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
        }
    }