This should be really simple!
I have a shop, it opens at 8:30 and closes at 17:00. I want my app to say the shops current open or currently closed.
Whats the best way to store my open_time and close_time? Store them as seconds since the start of the day, i.e. 30600 and 63000?
This make sense, but how do I get the current time right now, in seconds since the begining of today, so I can check if current_time is between open_time and close_time, i.e. open!!
Thanks in advance!
This problem isn't quite as trivial as you may think. You have to work with dates very carefully. The best solution is to store all of your open and close times as dates. Here is some code for creating your open/close times and comparing them:
NSDate * now = [NSDate date];
NSCalendar * calendar = [NSCalendar currentCalendar];
NSDateComponents * comps = [calendar components:~(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:now];
[comps setHour:8];
[comps setMinute:30];
NSDate * open = [calendar dateFromComponents:comps];
[comps setHour:17];
[comps setMinute:0];
NSDate * close = [calendar dateFromComponents:comps];
if ([now compare:open] == NSOrderedDescending && [now compare:close] == NSOrderedAscending) {
// The date is within the shop's hours.
}
else {
// The date is not within the shop's hours.
}
Here's what I did:
Grab the current date.
Get the components of the date, except hours, minutes, and seconds.
Set the hour and minutes.
Create an open time.
Repeat steps 3-4 for close time.
Compare open and close times to now.
If you ever need to do any modification of dates, you should always use NSCalendar and NSDateComponents. Check out this answer for why it's so important.
I think a clearer solution would be to use NSDate objects with only hour/minute components present.
Basically, somewhere in your app you need to store the shop's open/close times as such:
NSCalendar *calendar = [[NSCalendar alloc]
initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *openTime = [[NSDateComponents alloc] init];
[openTime setHour: 12];
[openTime setMinute: 30];
NSDate *openDate = [calendar dateFromComponents: openTime];
[calendar release];
And if you need to see whether the current time is between two such NSDate objects you could have a method like this:
- (BOOL)currentTimeIsInBetween: (NSDate *)date1 andDate: (NSDate *)date2 {
NSCalendar *calendar = [[NSCalendar alloc]
initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *currentComponents = [calendar components:
(NSMinuteCalendarUnit | NSHourCalendarUnit)
fromDate: [NSDate date]];
NSDate *currentAdjusted = [calendar dateFromComponents: currentComponents];
[calendar release];
if ([currentAdjusted compare: date1] == NSOrderedAscending)
return NO;
if ([currentAdjusted compare: date2] == NSOrderedDescending)
return NO;
return YES;
}
EDIT: Seems like user rbrown was a bit faster than me, we are suggesting the same approach.
You can do something like this.
NSDate *today = // code for getting today date at 0 oclock
NSDate *now = [NSDate date];
double second = [now timeIntervalSinceDate:today];
Now you got time in second since the start of the day for compare.
Related
I need to make a calendar in which the user can scroll between several weeks. The first and last day of the week will be displayed like (e.g.) "June 4 - June 10".
Now I knew from the beginning that I'd need NSDate and NSCalendar, and indeed I managed to get the first and last day of just thist week, but it looks extremely cumbersome and I am sure there needs to be an easier method, as I need to get the dates for several more coming and past weeks.
This is my code which gives the day and month of the first and last day of the current week:
NSDate *today = [NSDate date];
NSCalendar* cal = [NSCalendar currentCalendar];
NSDateComponents* comp = [cal components:(NSWeekdayCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSYearCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit) fromDate:[NSDate date]];
NSDate *beginOfWeek = [today dateByAddingTimeInterval: -1*([comp weekday]-2)*24*3600];
NSDate *endOfWeek = [today dateByAddingTimeInterval:(7-[comp weekday]+2)*24*3600];
NSLog(#"beginWeekDay=%d\n",[[cal components:(NSWeekdayCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSDayCalendarUnit) fromDate: beginOfWeek] day]);
NSLog(#"endWeekDay=%d\n",[[cal components:(NSWeekdayCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSDayCalendarUnit) fromDate: endOfWeek] day]);
NSLog(#"beginWeekmonth=%d\n",[[cal components:(NSWeekdayCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSDayCalendarUnit) fromDate: beginOfWeek] month]);
NSLog(#"endWeekmonth=%d\n",[[cal components:(NSWeekdayCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSDayCalendarUnit) fromDate: endOfWeek] month]);
I found this, which may be helpful to you: http://www.cocoanetics.com/2009/11/add-one-week-skip-weekend/
- (NSDate *)addWeekToDateAndSkipWeekend:(NSDate *)now {
int daysToAdd = 6; // we'll add the 7th later
// set up date components
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
[components setDay:daysToAdd];
// create a calendar
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDate *newDate = [gregorian dateByAddingComponents:components toDate:now options:0];
[components setDay:1]; // reuse to skip single days
NSDateComponents *newDateComps; // new componets to get weekday
// do always executed once, so we add the 7th day here
do
{
// add one day
newDate = [gregorian dateByAddingComponents:components toDate:newDate options:0];
newDateComps = [gregorian components:NSWeekdayCalendarUnit fromDate:newDate];
// repeat if the date is Saturday (7) or Sunday (1)
NSLog(#"weekday: %d", [newDateComps weekday]);
} while (([newDateComps weekday]==7)||([newDateComps weekday]==1));
return newDate;
}
Theoretically, you run this in a for loop with [NSDate date] and you will get the 7th day returned, you would then run the returned 7th day through this and get the next..etc..
May need minor alteration, to remove the check for Saturday+Sunday if you don't need it.
Hope this helps !
I searched it a lot but coudn't find any instance of showing how to store the specified time. For example, i need to save time of 15:48 in code in a proper variable (i guess that should be NSDate object). That is needed because i want to hold the exact time to replace the method below with not the time interval since now but my exact specified time to fire notification. Thanks for the help.
NSDate *notificationDate = [NSDate dateWithTimeIntervalSinceNow:5];
notification.fireDate = notificationDate;
Use NSDateComponents:
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setHour:15]; // 15:48 from your example
[comps setMinute:48]; // 15:48 from your example
/// also set year, month and day
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
You can also use NSDateCompnents to read the components from the current date and time - so if you want to set an NSDate to 15:48 today, you would first create an NSDate for now and then extract the day, month and year from it but overwrite the hour and minutes.
Use NSDateComponents to generate an NSDate object. I guess the Apple document is what you want http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateComponents_Class/Reference/Reference.html
Take a look at NSDateFormatter and especially - (NSDate *)dateFromString:(NSString *)string
I am writing a categorie in Xcode, that would extend the current NSDate class. I want to add two methods which I use regularly and somehow I can't get them to work properly.
Currently I have this code:
+ (NSDate*) today
{
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *todayComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:[NSDate date]];
NSInteger theDay = [todayComponents day];
NSInteger theMonth = [todayComponents month];
NSInteger theYear = [todayComponents year];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:theDay];
[components setMonth:theMonth];
[components setYear:theYear];
NSDate* todayDate = [gregorian dateFromComponents:components];
[components release];
[gregorian release];
return todayDate;
}
I want it to return a date like this: "2010-11-03 00:00:00 +01". But somehow the timezone keeps buggin me, because this code returns "2010-11-02 23:00:00 +0000".
Can anyone tell me how to fix this code to actually return the correct date? Or can I just use this date and my application will convert it itself because of the timezone the machine is set to.
I have to log certain events in my app to a database, which also just uses the [NSDate date] method. Does that mean that the [NSDate date] method also uses the time without timezone information?
EDIT:
I think it has something to do with the Daylight savings time bug. The things I see is exactly the same as probably the Clock app has, with the bug making people wake up late. Also, the TimeZone defaults to the TimeZone currently set on your device, so it should stay the same until you change the timezone in your settings screen.
EDIT2:
Ok, some more tests:
NSLog(#"CurrentDate: %#", [NSDate date]);
NSLog(#"TZ: %#", [NSTimeZone defaultTimeZone]);
Gives me the following results:
2010-11-03 23:23:49.000 App[8578:207] CurrentDate: 2010-11-03 22:23:49 +0000
2010-11-03 23:23:49.001 App[8578:207] TZ: Europe/Amsterdam (GMT+01:00) offset 3600
See Using Time Zones. You'll want to set the calendar's time zone using NSCalendar's -setTimeZone: method before you start asking it for dates.
This is an interesting question and I worked at a solution for many hours. These are my findings:
NSLog(#"CurrentDate: %#", [NSDate date]);
The code shown above will have the same result as the code shown below:
NSLog(#"CurrentDate: %#", [[NSDate date] description]);
Reading through the NSDate Class Reference produces this documentation on the NSDate's description method.
The representation is not guaranteed to remain constant across different releases of the operating system. To format a date, you should use a date formatter object instead (see NSDateFormatter and Data Formatting Guide)
I also ran across the documentation for descriptionWithLocale: (id) locale:
“Returns a string representation of the receiver using the given locale.”
So, change your code
NSLog(#"CurrentDate: %#", [NSDate date]);
To:
NSLog(#"CurrentDate: %#", [[NSDate date] descriptionWithLocale:[NSLocale currentLocale]]);
Which should result in what you are looking for. And I can also prove that the [NSDate date] really give's the correct date, but is just being displayed with wrong method:
We can use the [today] (Wim Haanstra) to create two dates.
dateLastDay: 2010-11-02 23:59:00 +01
dateToday: 2010-11-03 24:01:00 +01
Then we use the code below to show the two dates:
NSLog(#"CurrentDate: %#", dateLastDay);
NSLog(#"CurrentDate: %#", dateToday);
Or:
NSLog(#"CurrentDate: %#", [dateLastDay description]);
NSLog(#"CurrentDate: %#", [dateToday description]);
The two groups show the same results, like this: "2010-11-02 22:59:00 +0000" and "2010-11-02 23:01:00 +0000". It looks like the two dates have the same ‘day’, but really?
Now we compare the days of the dates:
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit;
NSDateComponents *lastDayComponents = [gregorian components:unitFlags fromDate:dateLastDay];
NSDateComponents *todayComponents = [gregorian components:unitFlags fromDate:dateToday];
NSInteger lastDay = [lastDayComponents day];
NSInteger today = [todayComponents day];
return (lastDay == today) ? YES : NO;
We will get NO! Although the two dates appear to have the same day, month and year, they DON'T. It only appears that way because we displayed them in the wrong way.
Did you try using:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
todayAtOO = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]];
I'm still trying to figure out exactly why this bug happens, but I do know a solution. Setting the timezone of your NSCalendar to GMT before sending it dateFromComponents: will solve the issue.
[gregorian setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
PS if there's a different solution that you found based on Joshua's suggestion, could you let us know what it is? It seems like you've solved the issue since you accepted his answer, but it's not really clear what you did. Thanks!
As far as I can see, it is giving you the correct answer if your timezone is GMT+1. Midnight your time is 23:00 the day before in GMT.
The problem is probably in formatting the returned date for output. It's given you a string for GMT instead of your current locale.
Can any one tell that how to find the date for the 3rd day from the current date iphone/ipad.
Thanks in advance
You can use this:
NSDate *today = [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setDay:3];
NSDate *threeDaysFromToday = [gregorian dateByAddingComponents:offsetComponents toDate:today options:0];
Slightly modified example from Apple's own documentation on NSDate. Check the link out for further info and more examples.
Here is Sample Code
NSDate * currentDate=[NSDate date];
NSTimeInterval interval=[currentDate timeIntervalSince1970];
NSTimeInterval intervalForThirdDate=interval+86400*3;
NSDate *nextDate=[[NSDate alloc]initWithTimeIntervalSince1970:intervalForThirdDate];
NSDate *today = [NSDate date];
NSTimeInterval threeDays = 86400*3;
NSDate *threeDaysFromToday = [NSDate dateWithTimeInterval:threeDays sinceDate:today];
choose one:
NSDate *futureDate;
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
[components setDay:3];
futureDate = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:[NSDate date] options:0];
NSLog(#"%# - %#", [NSDate date], futureDate);
NSDate *futureDate = [[NSDate date] dateByAddingTimeInterval:3 * (24*60*60)];
[NSDate dateWithTimeIntervalSinceNow:86400*3]
But as someone mentioned above, DST might make this too inaccurate. Depends on how important that is.
Something like:
// get the gregorian calendar ready to go; use the getter for the current system
// calendar if you're happy to deal with other calendars too
NSCalendar *gregorianCalendar = [[NSCalendar alloc]
initWithCalendarIdentifier: NSGregorianCalendar];
// get an NSDate object that is three days in the future
NSDate *dateInFuture = [NSDate dateWithTimeIntervalSinceNow:3*24*60*60];
// grab the date components for the bits we want to print in this example
NSDateComponents *componentsOfDateInFuture =
[gregorianCalendar
components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:dateInFuture];
// and print
NSLog(#"in three days it'll be %04d/%02d/%02d",
componentsOfDateInFuture.year,
componentsOfDateInFuture.month,
componentsOfDateInFuture.day);
// clean up
[gregorianCalendar release];
EDIT: Pablo Santa Cruz's answer is better for ensuring you're three days in the future, given daylight savings concerns. This is how you'd decompose an NSDate to day/month/year though, for the purposes of having the date rather than simply an NSDate.
Does anyone know if there is a way to set the first day of the week on a NSCalendar, or is there a calendar that already has Monday as the first day of the week, instead of Sunday.
I'm currently working on an app that is based around a week's worth of work, and it needs to start on Monday, not Sunday. I can most likely do some work to work around this, but there will be a lot of corner cases. I'd prefer the platform do it for me.
Thanks in advance
Here's some the code that I'm using. it's saturday now, so what I would hope is that weekday would be 6, instead of 7. that would mean that Sunday would be 7 instead of rolling over to 0
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setFirstWeekday:0];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit;
NSDateComponents *todaysDate = [gregorian components:unitFlags fromDate:[NSDate date]];
int dayOfWeek = todaysDate.weekday;
Edit: This does not check the edge case where the beginning of the week starts in the prior month. Some updated code to cover this: https://stackoverflow.com/a/14688780/308315
In case anyone is still paying attention to this, you need to use
ordinalityOfUnit:inUnit:forDate:
and set firstWeekday to 2. (1 == Sunday and 7 == Saturday)
Here's the code:
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[gregorian setFirstWeekday:2]; // Sunday == 1, Saturday == 7
NSUInteger adjustedWeekdayOrdinal = [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:[NSDate date]];
NSLog(#"Adjusted weekday ordinal: %d", adjustedWeekdayOrdinal);
Remember, the ordinals for weekdays start at 1 for the first day of the week, not zero.
Documentation link.
This code constructs a date that is set to Monday of the current week:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *today = [NSDate date];
NSDate *beginningOfWeek = nil;
BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek
interval:NULL forDate: today];
setFirstWeekday: on the NSCalendar object.
Sets the index of the first weekday for the receiver.
- (void)setFirstWeekday:(NSUInteger)weekday
Should do the trick.
In my opinion this settings should be dynamic according to the user locale.
Therefore one should use:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setLocale:[NSLocale currentLocale]];
This will cause the calendar to set the first week day according to the user locale automatically. Unless you are developing your app for a specific purpose/user locale (or prefer to allow the user to choose this day).
I've done it like this.
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *today = [NSDate date];
NSDateComponents *compForWeekday = [gregorian components:(NSWeekdayCalendarUnit) fromDate:today];
NSInteger weekDayAsNumber = [compForWeekday weekday]; // The week day as number but with sunday starting as 1
weekDayAsNumber = ((weekDayAsNumber + 5) % 7) + 1; // Transforming so that monday = 1 and sunday = 7
I had trouble with a lot of the answers here. . maybe it was just me. .
Here's an answer that works for me:
- (NSDate*)firstDayOfWeek
{
NSCalendar* cal = [[NSCalendar currentCalendar] copy];
[cal setFirstWeekday:2]; //Override locale to make week start on Monday
NSDate* startOfTheWeek;
NSTimeInterval interval;
[cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self];
return startOfTheWeek;
}
- (NSDate*)lastDayOfWeek
{
NSCalendar* cal = [[NSCalendar currentCalendar] copy];
[cal setFirstWeekday:2]; //Override locale to make week start on Monday
NSDate* startOfTheWeek;
NSTimeInterval interval;
[cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self];
return [startOfTheWeek dateByAddingTimeInterval:interval - 1];
}
Update:
As pointed out (elsewhere) by #vikingosegundo, in general its best to let the local determine which day is the start of the week, however in this case the OP was asking for the start of the week to occur on Monday, hence we copy the system calendar, and override the firstWeekDay.
The problem with Kris' answer is the edge case where the beginning of the week starts in the prior month. Here's some easier code and it also checks the edge case:
// Finds the date for the first day of the week
- (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate
{
NSCalendar *calendar = [NSCalendar currentCalendar];
// Edge case where beginning of week starts in the prior month
NSDateComponents *edgeCase = [[NSDateComponents alloc] init];
[edgeCase setMonth:2];
[edgeCase setDay:1];
[edgeCase setYear:2013];
NSDate *edgeCaseDate = [calendar dateFromComponents:edgeCase];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:edgeCaseDate];
[components setWeekday:1]; // 1 == Sunday, 7 == Saturday
[components setWeek:[components week]];
NSLog(#"Edge case date is %# and beginning of that week is %#", edgeCaseDate , [calendar dateFromComponents:components]);
// Find Sunday for the given date
components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate];
[components setWeekday:1]; // 1 == Sunday, 7 == Saturday
[components setWeek:[components week]];
NSLog(#"Original date is %# and beginning of week is %#", givenDate , [calendar dateFromComponents:components]);
return [calendar dateFromComponents:components];
}
I see misunderstanding in the other messages. The first weekday, whichever it is, has number 1 not 0. By default Sunday=1 as in the "Introduction to Date and Time Programming Guide for Cocoa: Calendrical Calculations":
"The weekday value for Sunday in the Gregorian calendar is 1"
For the Monday as a first workday the only remedy I have is brute force condition to fix the calculation
NSCalendar *cal=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [cal components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
// set to 7 if it's Sunday otherwise decrease weekday number
NSInteger weekday=[comps weekday]==1?7:[comps weekday]-1;
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];
}
You can just change .firstWeekday of the calendar.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
calendar.firstWeekday = 2;
Then use rangeOfUnit:startDate:interval:forDate: to get the first day
NSDate *startOfWeek;
[calendar rangeOfUnit:NSCalendarUnitWeekOfYear startDate:&startOfWeek interval:nil forDate:[NSdate date]];
Try this:
NSCalendar *yourCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]
[yourCal setFirstWeekday:0];
Iv found out the way to display any weekday name using nscalender..using the following code..
Just open your console from xcode menu bar to see the results.Copy Paste the following code in your viewDidLoad method to get the first day of the week
NSDate *today = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM/dd/yyyy :EEEE"];
NSString *dateString = [dateFormat stringFromDate:today];
NSLog(#"date: %#", dateString);
[dateFormat release];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today];
[components setDay:([components day]-([components weekday]-1))];
NSDate *beginningOfWeek = [gregorian dateFromComponents:components];
NSDateFormatter *dateFormat_first = [[NSDateFormatter alloc] init];
[dateFormat_first setDateFormat:#"MM/dd/yyyy :EEEE"];
NSString *dateString_first = [dateFormat_first stringFromDate:beginningOfWeek];
NSLog(#"First_date: %#", dateString_first);
The Output will be:
date: 02/11/2010 :Thursday
First_date: 02/07/2010 :Sunday
since i had run this program on 2/11/2010 u will get the desired output depending on the current date.
Similarly if u want to get the first working day of the week i.e Monday's date then just modify the code a bit:
CHANGE :[components setDay:([components day]-([components weekday]-1))];
TO
[components setDay:([components day]-([components weekday]-2))];
to get Mondays date for that week..
Similarly u can try to find the date of any of seven workdays by changing the integer -1,-2 and so on...
Hope u r question is answered..
Thanks,
Bonson Dias
The ISO 8601 calendar appears to have it's first weekday set to monday by default.
Using the Calendar nextWeekend (iOS 10 or later) and ordinality (thanks #kris-markel). I've gotten Monday as first of the week for the en_US calendar.
Here is an example of it with fallback to firstWeekday:
extension Calendar {
var firstWorkWeekday: Int {
guard #available(iOS 10.0, *) else{
return self.firstWeekday
}
guard let endOfWeekend = self.nextWeekend(startingAfter: Date())?.end else {
return self.firstWeekday
}
return self.ordinality(of: .weekday, in: .weekOfYear, for: endOfWeekend) ?? self.firstWeekday
}
}
The Swift solution (note, use .yearForWeekOfYear, not .year):
let now = Date()
let cal = Calendar.current
var weekComponents = cal.dateComponents([.yearForWeekOfYear, .weekOfYear,
.weekday], from: now)
//weekComponents.weekday = 1 // if your week starts on Sunday
weekComponents.weekday = 2 // if your week starts on Monday
cal.date(from: weekComponents) // returns date with first day of the week
… is there a calendar that already has Monday as the first day of the week, instead of Sunday.
Someday, there will be.
My simple way of doing this is to get Monday = 0, Sunday = 6:
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
NSInteger dayNumStartingFromMonday = ([dateComponents weekday] - 2 + 7) % 7; //normal: Sunday is 1, Monday is 2