How to get days of current week? - objective-c

How can I get an array of days of current week?
For example - today is saturday - 28 july.
I need array with '28 Saturday', 27 Friday, 26 Thursday,25 Wednesday ... 22 Sunday?
[code] NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *currentComps = [myCalendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekOfYearCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:weekDate];
int ff = currentComps.weekOfYear;
NSLog(#"1 %d", ff);
[currentComps setWeekday:1]; // 1: sunday
NSDate *firstDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
[currentComps setWeekday:7]; // 7: saturday
NSDate *lastDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
NSLog(#"first - %# \nlast - %#", firstDayOfTheWeek, lastDayOfTheWeek); [code]
I did this, but I have 'firstDayOfWeek' - 2012-07-29 and 'lastDayOfWeek' - 2012-08-04

Here is what you're looking for - you just need to format the result accordingly:
NSDate *weekDate = [NSDate date];
NSCalendar *myCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *currentComps = [myCalendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekOfYearCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:weekDate];
int ff = currentComps.weekOfYear;
NSLog(#"1 %d", ff);
[currentComps setWeekday:1]; // 1: sunday
NSDate *firstDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
[currentComps setWeekday:7]; // 7: saturday
NSDate *lastDayOfTheWeek = [myCalendar dateFromComponents:currentComps];
NSDateFormatter *myDateFormatter = [[NSDateFormatter alloc] init];
myDateFormatter.dateFormat = #"dd EEEE";
NSString *firstStr = [myDateFormatter stringFromDate:firstDayOfTheWeek];
NSString *secondStr = [myDateFormatter stringFromDate:lastDayOfTheWeek];
NSLog(#"first - %# \nlast - %#", firstStr, secondStr);

Related

Xcode - Set week of month, then get the week of year

Currently trying to use NSDateFormatter and NSDateComponents to set the week number for a month, then find the week of year that would be.
Let’s say we have a date: 20/05/2020, then set the week number to 0, or 1, or 2, etc.. then find out the week of year from that.
So far with NSDateComponents I’ve tried doing:
NSDate *date = self.date; // 20/05/2020
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
[components setWeekOfMonth:1];
NSDate *newDate = [calendar dateFromComponents:components];
NSInteger weekOfYear = [calendar components:NSCalendarUnitWeekOfYear fromDate:newDate].weekOfYear;
I'm always getting the output 18.
Expected output:
Change week of month to: 1 | output: 19 (4th)
Change week of month to: 2 | output: 20 (11th)
Change week of month to: 3 | output: 21 (18th)
Change week of month to: 4 | output: 22 (25th)
The problem is setting setWeekOfMonth in the date components has no effect.
Instead set the weekday and weekdayOrdinal
NSDate *date = self.date; // 20/05/2020
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
components.weekday = 2;
components.weekdayOrdinal = 3;
NSDate *newDate = [calendar dateFromComponents:components];
NSInteger weekOfYear = [calendar components:NSCalendarUnitWeekOfYear fromDate:newDate].weekOfYear;
This is a different approach:
It calculates the first monday in the current month, then it enumerates the next mondays until the end of the month.
- (NSArray *)yearOfWeeksInCurrentMonth
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components: NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
components.weekday = 2;
components.weekdayOrdinal = 1;
NSDate *firstMonday = [calendar dateFromComponents:components];
NSInteger weekOfYear = [calendar component:NSCalendarUnitWeekOfYear fromDate:firstMonday];
__block NSMutableArray *result = [NSMutableArray array];
[result addObject:#[firstMonday, #(weekOfYear)]];
NSDateComponents *weekComponents = [calendar components: NSCalendarUnitWeekday fromDate:firstMonday];
[calendar enumerateDatesStartingAfterDate:firstMonday matchingComponents:weekComponents options:NSCalendarMatchNextTime usingBlock:^(NSDate * _Nullable date, BOOL exactMatch, BOOL * _Nonnull stop) {
if (date != nil) {
if ( [calendar component:NSCalendarUnitMonth fromDate:date] > components.month ) {
*stop = YES;
} else {
NSInteger weekOfYear = [calendar component:NSCalendarUnitWeekOfYear fromDate:date];
[result addObject:#[date, #(weekOfYear)]];
}
}
}];
return [result copy];
}
The return value is an array containing the date (NSDate) and the corresponding weekOfYear (NSNumber)
(
(
"2020-05-03 22:00:00 +0000",
19
),
(
"2020-05-10 22:00:00 +0000",
20
),
(
"2020-05-17 22:00:00 +0000",
21
),
(
"2020-05-24 22:00:00 +0000",
22
)
)

Compare three dates

I have three dates 'startDate', stopDate and currentDate. I need compare 'startDate' <= 'currentDate' and 'stopDate' >= 'currentDate'. My code.
unsigned int flagsDate = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* fromComponents = [[NSCalendar currentCalendar] components:flagsDate fromDate:startDate];
NSDate* fromDateOnly = [[NSCalendar currentCalendar] dateFromComponents:fromComponents];
NSDateComponents* toComponents = [[NSCalendar currentCalendar] components:flagsDate fromDate:stopDate];
NSDate* toDateOnly = [[NSCalendar currentCalendar] dateFromComponents:toComponents];
NSDate * currentDate = [NSDate date];
NSDateComponents* currComponents = [[NSCalendar currentCalendar] components:flagsDate fromDate: currentDate];
NSDate* currDateOnly = [[NSCalendar currentCalendar] dateFromComponents:currComponents];
NSTimeInterval fromTime = [fromDateOnly timeIntervalSinceReferenceDate];
NSTimeInterval toTime = [toDateOnly timeIntervalSinceReferenceDate];
NSTimeInterval currTime = [currDateOnly timeIntervalSinceReferenceDate];
NSLog(#"%# %#",currentDate, currDateOnly);
NSLog(#"%# %#",startDate, fromDateOnly);
NSLog(#"%# %#",stopDate, toDateOnly);
That's what brings nslog.
2014-04-10 23:59:53.280 Calendar[2148:90b] 2014-04-10 19:59:53 +0000 2014-04-09 20:00:00 +0000
2014-04-10 23:59:53.282 Calendar[2148:90b] 2014-04-10 20:14:12 +0000 2014-04-10 20:00:00 +0000
2014-04-10 23:59:53.282 Calendar[2148:90b] 2015-04-09 20:14:12 +0000 2015-04-09 20:00:00 +0000
How do I compare dates? I need to compare dates only without time. Why change the date if time is less than 20:00?
NSTimeInterval distanceBetweenDates = [StartDate timeIntervalSinceDate:EndDate];
if (distanceBetweenDates > 0) {
NSLog("Greather than ")
} else if (distanceBetweenDates < 0) {
NSLog("less than");
} else {
NSLog("Equal");
}
Alexey, I suggest you incorporate this wonderful NSDate extension in your project: https://github.com/erica/NSDate-Extensions
You can then use
- (NSInteger)distanceInDaysToDate:(NSDate *)anotherDate
And check if it's < 0, 0 or > 0
If you wanted to compare only the dates, do as follows:
NSInteger flagsDate = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);
NSDateComponents* fromComponents = [[NSCalendar currentCalendar] components:flagsDate fromDate:startDate];
NSDateComponents* toComponents = [[NSCalendar currentCalendar] components:flagsDate fromDate:stopDate];
NSDateComponents* currComponents = [[NSCalendar currentCalendar] components:flagsDate fromDate:cu];
NSComparisonResult firstComparison = [[fromComponents date] compare: [currComponents date]];
NSComparisonResult secondComparison = [[toComponents date] compare: [currComponents date]];
then to check your result
if (firstComparison == NSOrderedDescending || firstComparison == NSOrderedSame) {}
if (secondComparison == NSOrderedSame || secondComparison == NSOrderedAscending) {}

Difference between NSDate and NSDateComponent value for the same date

I created a simple function to get first and last day of a week for a day in it.
Looking at the NSLog output i found that different values are returned from a NSDate descriptor and component day for the same date, why ?
Here NSLog outputs:
NSDATE: 2011-04-03 22:00:00 +0000, DAY COMPONENT: 4
NSDATE: 2011-04-09 22:00:00 +0000, DAY COMPONENT: 10
As you can see, NSDATE is 3 of April and day component is 4 for the first row, and respectively 9 and 10 for the second one.
Here the code:
NSDate *date = [NSDate date]; //Today is April 5th 2011
NSCalendar *cal =[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
[cal setFirstWeekday:2]; //My week starts from Monday
//DEFINE BEGINNING OF THE WEEK
NSDate *beginningOfWeek = nil;
[cal rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek interval:nil forDate:date];
NSDateComponents *beginComponents = [cal components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit) fromDate:beginningOfWeek];
//DEFINE END OF THE WEEK, WITH 6 days OFFSET FROM BEGINNING
NSDateComponents *offset = [[NSDateComponents alloc]init];
[offset setDay:6];
NSDate *endOfWeek = [cal dateByAddingComponents:offset toDate:beginningOfWeek options:0];
NSDateComponents *endComponents = [cal components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit) fromDate:endOfWeek];
NSLog(#"NSDATE: %#, DAY COMPONENT: %d",beginningOfWeek, [beginComponents day]);
NSLog(#"NSDATE: %#, DAY COMPONENT: %d",endOfWeek, [endComponents day]);
Your dates are being printed with a timezone of +0000 (UTC), while your NSCalendar instance (and therefore your NSDateComponents) is using your device's default timezone (which I would guess is UTC+2).

Getting first day of a week with NSDateComponents : changing year

Hello
I have a problem with setting a firstWeekDay, here is what I do:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
comp = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit) fromDate:targetDate];
[comp setWeekday:2];
NSDate *firstWeekDay = [gregorian dateFromComponents:comp];
If Saturday 2011-01-01 is targetDate, the firstWeekDay in my calendar appears to be Monday 2011-12-26, but in fact it should be Monday 2010-12-26. How can I make it right?
To fix this problem, Add NSYearForWeekOfYearCalendarUnit in the NSDateComponents.
Ex:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:NSYearForWeekOfYearCalendarUnit |NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:curDate];
[comps setWeekday:2]; // 2: monday
firstDayOfTheWeek = [calendar dateFromComponents:comps];
[comps setWeekday:7]; // 7: saturday
lastDayOfTheWeek = [calendar dateFromComponents:comps];
Try this
// adjust them for first day of previous week (Monday)
[comp setWeekday:2];
[comp setWeek:([comp week] - 1)];
Note this solution assumes the first day of the week is Monday.
Below also covers the edge case,
- (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate];
[components setWeekday:2]; // 1 == Sunday, 7 == Saturday
if([[calendar dateFromComponents:components] compare: curDate] == NSOrderedDescending) // if start is later in time than end
{
[components setWeek:[components week]-1];
}
return [calendar dateFromComponents:components];
}
The Swift solution (thanks #YvesJusot):
let calendar = NSCalendar.currentCalendar()
let comps = calendar.components(NSCalendarUnit.WeekOfYearCalendarUnit|NSCalendarUnit.YearCalendarUnit|NSCalendarUnit.MonthCalendarUnit|NSCalendarUnit.WeekCalendarUnit|NSCalendarUnit.WeekdayCalendarUnit, fromDate: NSDate()) as NSDateComponents
comps.setValue(2, forComponent: NSCalendarUnit.WeekdayCalendarUnit)
let monday = calendar.dateFromComponents(comps)!
println("\(monday)")
You suppose to use dynamic values instead of hardcoding 2 as Monday!
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:NSYearForWeekOfYearCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:[NSDate date]];
comps.weekday = calendar.firstWeekday;
firstDayOfTheWeek = [calendar dateFromComponents:comps];
comps.weekday = calendar.firstWeekday - 1;
lastDayOfTheWeek = [calendar dateFromComponents:comps];
I did some changes in #JasonGarrett answer and it works for me.
let calendar = NSCalendar.currentCalendar()
let flags : NSCalendarUnit = NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitYear
let comps = calendar.components(flags, fromDate: NSDate()) as NSDateComponents
comps.setValue(2, forComponent: NSCalendarUnit.CalendarUnitWeekday)
let monday = calendar.dateFromComponents(comps)!
// Make these two methods as categories to NSDate
// Use This to get First date of the week (Monday)
- (NSDate *) getFirstDayOfWeek {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *compOfDate = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday) fromDate:self];
NSInteger numOfDaysToAdd = compOfDate.weekday == 1 ? -6 : (2 - compOfDate.weekday);
NSDateComponents *compToAdd = [[NSDateComponents alloc] init];
compToAdd.day = numOfDaysToAdd;
return [calendar dateByAddingComponents:compToAdd toDate:self options:0];
}
// Use This to get last date of the week (Sunday)
- (NSDate *)getLastDayOfWeek {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *compOfDate = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday) fromDate:self];
NSInteger numOfDaysToAdd = compOfDate.weekday == 1 ? 0 : (8 - compOfDate.weekday);
NSDateComponents *compToAdd = [[NSDateComponents alloc] init];
compToAdd.day = numOfDaysToAdd;
return [calendar dateByAddingComponents:compToAdd toDate:self options:0];
}

iPhone NSDate eg. next Friday

I want to create a function which results the date of next Friday but I have no plan how to do it. Has anyone a good hint to me ?
E.g. Get current date using NSDate, then use 'components>fromDate:' from NSCalendar to get the NSDateComponents, then add the time difference to next Friday and create a new NSDate and Bob's is your uncle.
Here is my working solution for getting the next 5 Sundays in Gregorian calendar:
self.nextBeginDates = [NSMutableArray array];
NSDateComponents *weekdayComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
int currentWeekday = [weekdayComponents weekday]; //[1;7] ... 1 is sunday, 7 is saturday in gregorian calendar
NSDateComponents *comp = [[NSDateComponents alloc] init];
[comp setDay:8 - currentWeekday]; // add some days so it will become sunday
// build weeks array
int weeksCount = 5;
for (int i = 0; i < weeksCount; i++) {
[comp setWeek:i]; // add weeks
[nextBeginDates addObject:[[NSCalendar currentCalendar] dateByAddingComponents:comp toDate:[NSDate date] options:0]];
}
[comp release];
This should work
+ (NSDate *) dateForNextWeekday: (NSInteger)weekday {
NSDate *today = [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
// Get the weekday component of the current date
NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit
fromDate:today];
/*
Add components to get to the weekday we want
*/
NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
NSInteger dif = weekday-weekdayComponents.weekday;
if (dif<=0) dif += 7;
[componentsToSubtract setDay:dif];
NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract
toDate:today options:0];
return beginningOfWeek;
}
Keep it simple, safe, and readable! (....KISSAR?)
#define FRIDAY 6
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
dayComponent.day = 1;
NSDate *nextFriday = [NSDate date];
NSInteger iWeekday = [[gregorian components:NSWeekdayCalendarUnit fromDate:nextFriday] weekday];
while (iWeekday != FRIDAY) {
nextFriday = [gregorian dateByAddingComponents:dayComponent toDate:nextFriday options:0];
iWeekday = [[gregorian components:NSWeekdayCalendarUnit fromDate:nextFriday] weekday];
}
Now nextFriday has your date.
Hope this helps!
EDIT
Note that if the current date was already a Friday, it would return that instead of the next Friday. If that's undesirable just init your nextFriday to a day later (so if current date was a Friday, it would start on Saturday, forcing the next Friday. And if current date was a Thursday you'd automatically have your next Friday without needing the loop).
Here is my solution, and just to warn you, on a saturday is the friday before shown.
cheers to all
NSDate *today = [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit fromDate:today];
int weekday = [weekdayComponents weekday];
int iOffsetToFryday = -weekday + 6;
weekdayComponents.weekday = iOffsetToFryday;
NSDate *nextFriday = [[NSCalendar currentCalendar] dateByAddingComponents:weekdayComponents toDate:today options:0];