Create an NSMutableArray using NSCalendar - iphone

I have following problem: I need to create an NSMutabeArray with every weekday after a specific date.
This should look like:
Thursday 28 october 2010
Thursday 04 october 2010
Thursday 11 october 2010
...
How can I do that? I think it has something to do with NSCalendar, but I can't find the right solution... Could you help me?
Thank you in advance
FFraenz

That's an infinite series; an NSMutableArray can only hold a finite collection.
At any rate, you need only a single member of the series, such as 2010-10-28. To get the Thursday after that, add one week. To get the third date in the series, add a week to the second date, or two weeks to the first date. Having any member of the series provides you with access to any other member of the series.
If you are starting from a date that isn't the right weekday, get the date components for that date, add the difference between the correct weekday and the weekday it has to its day of the month, and convert the amended date components back to a date. That date will then be on the desired weekday in the same week.

To have actual date:
NSDate *today = [[NSDate alloc] init];
To add a week:
NSDate *nextDate = [today dateByAddingTimeInterval:60*60*24*7];
Then you can iterate and create your array:
NSMutableArray* dates = [[NSMutableArray alloc] init];
NSDate *date= [[NSDate alloc] init];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setWeek:1];
for (int i=0;i<10;i++) {
NSDate *nextDate = [gregorian dateByAddingComponents:offsetComponents toDate:date options:0];
[dates addObject:date];
[date release];
date = nextDate;
}
[date release];

Related

How to get date from day of the year in iPhone?

How do I get date from the day of the year?
for e.g., if I give day as "1" then date should be "January 1"
How do I get that in iPhone? I have found answer in javascript but I want to know how to do the achieve same thing in Objective?
I guess this code will work for you:
I have created a sample function where a textfield gives input values for how many days to add. And a button to calculate final day. Here is the button event logic.
NSDateComponents *dateComponent = [[NSDateComponents alloc] init];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-mm-dd"];
NSDate *newDate = [formatter dateFromString:#"2012-01-01"];
// add days to current date
dateComponent.day = [dayTextField.text intValue];
// get a new date by adding components
newDate = [[NSCalendar currentCalendar] dateByAddingComponents: dateComponent toDate:newDate options:0];
[finalDate setText:[NSString stringWithFormat:#"%#", newDate]];
Here dayTextField.text is the text which says how many number of days want to calculated. (For example 125 days) and finalDate is an label which displays final generated date (means date after 125 days since 1 Jan 2012).
Benefit of this code is, any time you can change the start day parameter. For example, for other requirement, i need to count my days from "31 May 1999" then i will change it easily in one line and the same code will work.
Enjoy Coding :)
NSCalendar *gregorian =
[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger dayOfYear =
[gregorian ordinalityOfUnit:NSDayCalendarUnit
inUnit:NSYearCalendarUnit forDate:[NSDate date]];
[gregorian release];
return dayOfYear;
Take from the post:
How do you calculate the day of the year for a specific date in Objective-C?

Get first and last day of week for a couple of weeks

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 !

How to get number of current week in objective-c?

I develop an app that needs to get the current week. I tried this:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *dateString = #"1-1-2011";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comp = [gregorian components:NSWeekCalendarUnit fromDate:dateFromString];
NSLog(#"%d", comp.week);
[dateFormatter release];
}
but it shows me 52. Which is actually a wrong result. Please, suggest me any ideas.
Thanks in advance.
The week date depends on which numbering standard is in use. For instance, the ISO-8601 standard defines week 1 of a year as "the week with the year's first Thursday in it".
The first of January 2011 was a Saturday, which means the following week was week 1 of 2011, making the week 27.12.2010–2.1.2011 week 52 of 2010.
Also, there's several incompatible standards for when weeks start or end and how weeks in a year are numbered. This makes week numbers a confusing way to specify a date range and the best solution to avoid using them.
From the documentation to NSCalendar, it seems you could also use setMinimumDaysInFirstWeek: to adjust the way it numbers weeks.

How to set time range in a day using UIDatePickerView

I am using UIDatePickerView, just like we can set the date range using "maximumDate" and "minimumDate", is there any way to set time range in a day like from 9.00 am to 6.00 pm ?
Not really. minimumDate and maximumDate can include a time of day (NSDate is more like a timestamp than a calendar date), but this only has an effect if they are both on the same day because otherwise all (clock) times are possible within the date range.
Actually you should set the time using these two as well. NSDate objects have both date and time components. You should do something like this:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
//set the date using setDate: setMonth: setYear:
[dateComponents setHour:9]; //setHour:18 for maximumDate
NSDate *targetDate = [gregorian dateFromComponents::dateComponents];
[dateComponents release];
[gregorian release];
datepick.minimumDate = targetDate;
If that doesnt help, have a look at these Qs:
UI Datepicker range. iPhone
How to set time on NSDate?

how to change nsdate in nsdictionary

I am trying to increment my NSDate. I have an NSDictionary, I am trying to increment my NSDate content in it. Say my NSDate is 2011-07-11, I want to increment the NSDate content in it.
got
{
ConditionDatenew = "2011-07-21 13:31:46 +0000";
Yesterday = "2011-07-20 13:31:46 +0000";
city = #;
condition = "Isolated Thunderstorms";
country = #;
"day_of_week" = Sun;
high = 86;
icon = "chance_of_storm.gif";
low = 68;
state = #;
}
I just want to get the date as 2011-07-22 in my ConditionDatenew in the next dictionary loop. How can I get it?
Create a new date object, and replace the old value in the dictionary. Dates are immutable.
NSDate *newDate = [NSDate date];
[dictionary setObject:newDate forKey:#"ConditionDatenew"];
[NSDate date] will set this to "now."
The easiest way to add a day is to add 24 hours. This works as long as DST is never an issue, and by "increment a day" you mean "increment by 24 hours." If you work exclusively in UTC, then that's fine.
NSDate *newDate = [oldDate dateByAddingTimeInterval:24*60*60];
If DST is an issue (and it usually is), and by "increment a day" you mean "increment by a Gregorian calendar day" then you need to use date components to make sure you add 23, 24 or 25 hours as appropriate.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear:2011];
[dateComponents setMonth:11];
[dateComponents setDay:6];
[dateComponents setTimeZone:[NSTimeZone timeZoneWithName:#"America/New_York"]];
NSDate *date = [calendar dateFromComponents:dateComponents];
NSDateComponents *addComponents = [[NSDateComponents alloc] init];
[addComponents setDay:1];
[addComponents setTimeZone:[NSTimeZone localTimeZone]];
NSDate *newDate = [calendar dateByAddingComponents:addComponents toDate:date options:0];
NSLog(#"oldDate=%#", [date descriptionWithLocale:[NSLocale currentLocale]]);
NSLog(#"+24=%#", [[date dateByAddingTimeInterval:24*60*60] descriptionWithLocale:[NSLocale currentLocale]]);
NSLog(#"newDate=%#", [newDate descriptionWithLocale:[NSLocale currentLocale]]);
[calendar release];
[dateComponents release];
[addComponents release];
Output:
oldDate=Sunday, November 6, 2011 12:00:00 AM Eastern Daylight Time
+24=Sunday, November 6, 2011 11:00:00 PM Eastern Standard Time
newDate=Monday, November 7, 2011 12:00:00 AM Eastern Standard Time
If you don't care about the time, and have control over what you set it to, one trick is to set the time to noon. That way adding 24 hours will always fall on the correct day. I don't generally recommend this because it fails badly if you ever forget and create a date with a time of midnight. It's easier to put all of your day-incrementing code in one place and fix the DST problem one time than to make sure all of your date creation code is always right. So I recommend getting used to date components.
Try this:
NSDate *newDate = [NSDate date];
[dictionary setValue:newDate forKey:#"ConditionDatenew"];