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