iPhone OS4.3: NSCalendar's [ordinalityOfUnit:inUnit:forDate:] method returns different/wrong result - nscalendar

I've following code snippet which I'm using to deduce the first day of the week, to display in my calendar view. This code has been working without any issue, till I tested it on iPhone OS 4.3 onwards.
int firstDOW = [m_calendar ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:fom]%7;
where 'fom' is the first date of the month.
When debugged the code, on iOS prior to 4.3, return value for 'ordinality' method seems to return correct value( for example if the 'fom' date falls on Friday, the value returned from above method is '5'). But on iOS >= 4.3, the return value is somehow not the correct weekday( for example, if the 'fom' date falls on Friday, the value returned from above method is '6'!).
I don't understand, whether there is any issue with my code, or it really is a bug in the above method.
Has anyone else faced this in iOS >= 4.3??
Thanks and Regards.

I learned a bit more about this method call. It appears that the ordinalityOfUnit:inUnit:forDate: method pays attention to what current locale is and what that locale considers the first day of the week to be.
For example. In the United States locale the first day of the week is considered to be Sunday while in the Ireland locale, the first day of the week is considered to be Monday.
If you are in the US locale, and ask for the ordinality of Tuesday, it will return 2 (0 for Sunday, 1 for Monday and 2 for Tuesday). In the Ireland locale, however, it will return 1 (0 for Monday and 1 for Tuesday).
In short, the ordinality of the day within the week depends on which day is considered to begin the week. In contrast, if you use the NSDateComponents API and get the day of the week from there, you always get a day relative to Sunday === 0. e.g.
NSDateComponents *components = [[self calendar] components: NSWeekdayCalendarUnit fromDate: [self startingDay]];
NSUInteger weekdayIndex = [components weekday];

Related

Why does ordinalityOfUnit use Monday as the first day of the week when using NSCalendarUnitEra?

I'm trying to calculate the number of calendar weeks between two dates. I'm using the following code:
[cal ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitEra forDate:thenDate];
[cal ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitEra forDate:nowDate];
A date of 15-1-2017, a Sunday, results in 105192 weeks, and 16-1-2017, a Monday, results in 105193. That would indicate it is using Monday as the first day of the week. I have verified that cal.firstWeekday is 1. If I change the inUnit from NSCalendarUnitEra to NSCalendarUnitYear it works correctly. Is there a way around this?
I suppose I could subtract one day from both dates but that seems very hackie.
After much experimenting, if you make sure all dates are in GMT and you set cal timeZone to GMT it works as one would expect.

Difference between Year and yearForWeekOfYear - iOS (NSDateComponents)

While working on NSDateComponents I come to know one property which I have never used.
I have try to look in apple document as well but didn't get proper answer.
Apple says,
Declaration
OBJECTIVE-C
#property NSInteger yearForWeekOfYear
Discussion
This value is interpreted in the context of the calendar with which it is used
Does anybody knows exactly what this property do ?
e.g.
- Year property will return year value.
- Day property will rerun day value
- MonthOfYear property will return month number of particular year
- WeekOfYear will return Week number of particular year
- yearForWeekOfYear will return ????? (Can anybody give simple example as well so I can easily understand )
yearForWeekOfYear are based off of something called the ISO Week Date, which is part of the ISO 8601 standard. You can read more about it on this Wikipedia page. The 52nd week of the year as we normally use it may not be the 52nd week according to the weekOfYear property, depending on which year you are in, and what day of the week the year starts on in the normal Gregorian calendar (as opposed to the ISO Week Date version of the Gregorian Calendar).

How to get start and end dat for week number in objective c

In my iOS app, I have a week number and I need to get the start and end date for that week number.
I'm building an app with which the manager of a company can keep track of the worked hours of staff. These worked hours are processed per day in a custom Registration object.
In this object, the date, begin time, end time and break time are stored and based on those values, the worked hours are calculated.
Then, all Registration objects are stored in a WorkWeek object, containing a week number and an array of registrations. WorkWeek's are constructed based on weeknumbers and run from monday through sunday. In this WorkWeek object, the total worked hours, extra hours and wage are calculated.
Now obviously, I can't reliably calculate extra hours if a Workweek is not a full week that runs from monday through friday. This particularly occurs when the user chooses to get all registrations from a mont from my database. A month does not start on monday and does not end on sunday exactly four weeks later, so i'm dealing with unreliable week object.
Wrapping up
To make sure the information I display in my app is reliable, I need to determine whether a certain week (like week 1 or week 52) contains at least 7 days and, if not, I need to set a bool to FALSE which then triggers a notification to my user.
How can I get the begin and end date of a week based on a weeknumer?
This shows how it could be done:
NSCalendar *cal = [NSCalendar currentCalendar];
// Start of week:
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.weekday = cal.firstWeekday;
comp.weekOfYear = 1; // <-- fill in your week number here
comp.year = 2015; // <-- fill in your year here
NSDate *startOfWeek = [cal dateFromComponents:comp];
// Add 6 days:
NSDate *endOfWeek = [cal dateByAddingUnit:NSCalendarUnitDay value:6 toDate:startOfWeek options:0];
// Show results:
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateStyle = NSDateFormatterShortStyle;
NSLog(#"%#", [fmt stringFromDate:startOfWeek]);
NSLog(#"%#", [fmt stringFromDate:endOfWeek]);
Some notes:
cal.firstWeekday gives the locale dependent index of the first weekday, e.g.
2 = Monday in Germany, or 1 = Sunday in the U.S. Depending on your needs,
you can also use a constant value here.
It might be necessary to set cal.minimumDaysInFirstWeek, compare
NSDateFormatter reports June 2, 2013 as being in week zero.
The dateByAddingUnit:... method is available in OS X 10.9 or later.
Alternatively, use dateByAddingComponents:....
I have assumed that you use the Gregorian calendar, so that a week has 7 days.
Alternatively, you can add one week and then subtract one day.

Get current date past midnight, Objective C

I want to get the current date, even if the time has passed midnight. Imagine it's friday night the 6th of June 2014 - we check the date Saturday at 2 am, but we still want this to count as being friday. How would I go about this?
Let's just say we cut it at 9am the next day. I.e. we will assume previous date until the time has passed 9 am. Yes, this is software used at a nightclub, as you can imagine.
I guess this would involve something like subtracting 1 day from the current date if the hour is less than 10?
You can use interval to specific date like
[[NSDate date] dateByAddingTimeInterval:interval];
Assuming the cutoff is 9am, all you need to do is create an NSDate that's 9 hours earlier than the actual time.
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:-(9 * 3600)];
That way every day begins and ends at 9am.

same day of last month ios

Is there any way using NSCalender you can get same day of last month?
I am using a calender which shows user 1 month like the iPad calender when they click on the button I want to move to previous month but should select the same day as before.
I want to just do
[components setMonth:([components month] - 1)];
but this will create problems when I are moving from a month with 31 days to month with 30 days and selected day is 31st.
I was able to find examples for android but not iOS.
android example
Any help would be appreciated
Check out this link.
It's about adding one month, but you could probably do the same with subtracting.
Change
[dateComponents setMonth:1];
into
[dateComponents setMonth:-1];
Seems there is no obvious "right" answer and no "built-in" answer.
As Chris's "simple" idea may lead to invalid dates, you may have to handle the edge-cases.
Pseudocode to deal with day-month-year:
if month = December start with day-1-(year-1), else
day-(month-1)-year [using dateComponents]
check if this a valid date (using NSDateFormatter like in this question
repeat subtracting one day until you reach a valid date
Another idea:
prevMonthDate = startDate;
Repeat
prevMonthDate = prevMonthDate - 1 day
Until (Month(prevMonthDate) < Month(startDate) Or Year(prevMonthDate) < Year(startDate))
And (Day(prevMonthDate) <= Day(startDate))
This requires working with NSDate and NSDateComponents, check out the Date and Time Programming Guide.

Resources