I know there are some questions similar to this one, but I just can't find what's wrong with my code.
Basically what I want is if today is not sunday, currentDate is set to the last sunday. If today is sunday I currentDate is set to the sunday before.
Here's how I'm trying to do it.
  NSDateComponents *components = [[NSCalendar currentCalendar] components:  NSWeekCalendarUnit | NSYearCalendarUnit | NSWeekdayCalendarUnit fromDate:currentDate];
    if (components.weekday == 1) { //Its sunday. We just need to subtract a week
        [components setWeek: -1];
        currentDate = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:currentDate options:0];
    }else{ //If its not sunday we just go to sunday
        [components setWeekday: 1];
        currentDate = [[NSCalendar currentCalendar] dateFromComponents:components];
    }
The first time this part of the code is executed I get the right answer. After the first time I get weird dates, like 02 Dec. 4026, and the year keeps going up.
Here's the code that made it work:
   NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components: ( NSWeekCalendarUnit | NSWeekdayCalendarUnit | NSYearCalendarUnit) fromDate:currentDate];
    int weekday = components.weekday;
    if (weekday == 1) {
        [components setWeek:components.week -1];
    }else{
        [components setWeekday:1];
    }
    currentDate = [calendar dateFromComponents:components];
Use nextDateAfterDate with the .SearchBackwards option if you are using iOS 8.0+
let calendar = NSCalendar.currentCalendar()
let options: NSCalendarOptions = [.MatchPreviousTimePreservingSmallerUnits, .SearchBackwards]
calendar.nextDateAfterDate(NSDate(), matchingUnit: .Weekday, value: 1, options: options)
Try this category on NSCalendar
@interface NSCalendar (LastSunday)
-(NSDate *)previousSundayForDate:(NSDate *)date;
@end
@implementation NSCalendar (LastSunday)
-(NSDate *)previousSundayForDate:(NSDate *)date
{
    static NSUInteger SUNDAY = 1;
    static NSUInteger MONDAY = 2;
    NSDate *startOfWeek;
    [self rangeOfUnit:NSWeekCalendarUnit
            startDate:&startOfWeek
             interval:NULL
              forDate:date];
    if(self.firstWeekday == SUNDAY){
        NSDate *beginningOfDate;
        [self rangeOfUnit:NSDayCalendarUnit
                startDate:&beginningOfDate
                 interval:NULL forDate:date];
        if ([startOfWeek isEqualToDate:beginningOfDate]) {
            startOfWeek = [self dateByAddingComponents:(
                                                        {
                                                            NSDateComponents *comps = [[NSDateComponents alloc] init];
                                                            comps.day = -7;
                                                            comps;
                                                        })
                                                toDate:startOfWeek
                                               options:0];
        }
        return startOfWeek;
    }
    if(self.firstWeekday == MONDAY)
        return [self dateByAddingComponents:(
                                             {
                                                 NSDateComponents *comps = [[NSDateComponents alloc] init];
                                                 comps.day = -1;
                                                 comps;
                                             })
                                     toDate:startOfWeek
                                    options:0];
    return nil;
}
@end
use it as:
NSDate *lastSunday = [calendar previousSundayForDate:[NSDate date]];
PS:
a version for "one-method-one-return-statement"- fetishists:
@implementation NSCalendar (LastSunday)
-(NSDate *)previousSundayForDate:(NSDate *)date
{
    NSDate *resultDate = nil;
    static NSUInteger SUNDAY = 1;
    static NSUInteger MONDAY = 2;
    NSDate *startOfWeek;
    [self rangeOfUnit:NSWeekCalendarUnit
            startDate:&startOfWeek
             interval:NULL
              forDate:date];
    if(self.firstWeekday == SUNDAY){
        NSDate *beginningOfDate;
        [self rangeOfUnit:NSDayCalendarUnit
                startDate:&beginningOfDate
                 interval:NULL forDate:date];
        if ([startOfWeek isEqualToDate:beginningOfDate]) {
            startOfWeek = [self dateByAddingComponents:(
                                                        {
                                                            NSDateComponents *comps = [[NSDateComponents alloc] init];
                                                            comps.day = -7;
                                                            comps;
                                                        })
                                                toDate:startOfWeek
                                               options:0];
        }
        resultDate = startOfWeek;
    }
    if(self.firstWeekday == MONDAY)
        resultDate = [self dateByAddingComponents:(
                                                   {
                                                       NSDateComponents *comps = [[NSDateComponents alloc] init];
                                                       comps.day = -1;
                                                       comps;
                                                   })
                                           toDate:startOfWeek
                                          options:0];
    return resultDate;
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With