get NSDate from the day of the year - objective-c

I have a the day of the year for example 346.
I want to get NSDate to now what month and day it means.

Your steps here:
Instantiate calendar
Build a date with 1st Jan. of the year
Add the number of days - 1 and build a date with that
Get the components you are interested in
Watch out if the date you get is 0- or 1-based.
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:theYear];
[comps setMonth:1];
[comps setDay:1];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
NSDateComponents *compsToAdd = [[NSDateComponents alloc] init];
[comps setDay:theDay-1];
NSDate *finalDate = [gregorian dateByAddingComponents:compsToAdd date options:0];
[compsToAdd release]
NSDateComponents *interestingComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit) fromDate:finalDate];
NSInteger day = [interestingComponents day];
NSInteger month = [interestingComponents month];
[gregorian release];

See the -dateByAddingComponents:toDate:options: method of NSCalendar.

Related

How to get absolute value from NSDateComponents

I want to take absolute value from NSDateComponents.
<NSDateComponents: 0x600000477c80>
Calendar Year: -1
I tried the following way.But I did not get the exact value.How can i get the value 1 from the components.
NSDate *startDate = [formatter dateFromString:birthDate];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitYear
fromDate:startDate
toDate:today
options:0];
NSInteger year = [components year];
If you want to get difference of the dates in the years, then you have to use method : calendar: fromDate: toDate:
And if you want to get only year from the date, then you have to use this method : calendar: fromDate:.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"dd/MM/yyyy hh:mm:ss"];
NSDate *today = [NSDate date];
NSString *birthDate = #"04/06/1984 01:45:20";
NSDate *startDate = [formatter dateFromString:birthDate];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
//NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitYear fromDate:startDate toDate:today options:0]; //Option 1
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitYear fromDate:startDate]; // Option 2
NSInteger year = [components year];
NSLog(#"Years : %ld", year);
If you use method of option 1, then it will print Years : 35.
And if you use method of option 2, then it will give Years : 1984.

Objective C: Incorrect Output while using NSDates

I am trying to get the start and end dates of the current month. There are a few similar questions here, but I am getting unexpected results while using them. Here's what I did:
NSDate *monthStart,*monthEnd;
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [cal components:NSDayCalendarUnit fromDate:[NSDate date]];
[comps setDay:1];
[comps setHour:0];
[comps setMinute:0];
[comps setSecond:0];
monthStart = [cal dateFromComponents:comps];
[comps setDay:[[NSCalendar currentCalendar]
rangeOfUnit:NSDayCalendarUnit
inUnit:NSMonthCalendarUnit
forDate:[NSDate date]].length];
[comps setHour:23];
[comps setMinute:59];
[comps setSecond:59];
monthEnd = [cal dateFromComponents:comps];
NSLog(#"%#",monthStart);
NSLog(#"%#",monthEnd);
Unfortunately the output is :
2012-12-24 15:39:28.159 Popup[1010:403] 0001-12-31 18:06:32 +0000
2012-12-24 15:39:28.160 Popup[1010:403] 0001-01-31 18:06:31 +0000
BTW, the timezone configured in my machine is +5:30
I have modified your code little, to get the correct answer
NSDate *monthStart,*monthEnd;
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *currentDate = [NSDate date];
NSDateComponents *comps = [cal components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:currentDate];
[comps setDay:1];
[comps setHour:0];
[comps setMinute:0];
[comps setSecond:0];
[cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:19800]];
monthStart = [cal dateFromComponents:comps];
[comps setDay:[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length];
[comps setHour:23];
[comps setMinute:59];
[comps setSecond:59];
monthEnd = [cal dateFromComponents:comps];
NSLog(#"Start %#",monthStart);
NSLog(#"End %#",monthEnd);
If you want to know the starting and ending date for current month...
Starting is always 1st, and ending can be calculated by month name!!!
Then it is very simple date arithmetic,
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
NSMutableArray *months=[NSMutableArray arrayWithObjects:#"Jan",#"Feb",#"Mar",#"Apr",#"May",#"Jun",#"Jul",#"Aug",#"Sep",#"Oct",#"Nov",#"Dec", nil];
NSMutableArray *days=[NSMutableArray arrayWithObjects:#"31",#"28",#"31",#"30",#"31",#"30",#"31",#"31",#"30",#"31",#"30",#"31", nil];
//check if leap
[dateFormat setDateFormat:#"YYYY"];
NSInteger year=[[dateFormat stringFromDate:[NSDate date]]integerValue];
if(((year%4==0)&&(year%100!=0))||(year%400==0)) {
[days replaceObjectAtIndex:1 withObject:#"29"];
}
NSMutableDictionary *daysInMonthDict=[[NSMutableDictionary alloc]initWithObjects:days forKeys:months];
[dateFormat setDateFormat:#"MMM"];
NSLog(#"Starting date is 1 and ending date is %#",[daysInMonthDict objectForKey:[dateFormat stringFromDate:[NSDate date]]]);

NSDate conversion setting weekday

I have an NSDate object *myDate.I can get the week day from this date and I want to set the weekday to an integer c and get the new date object in that week only.
I searched for it and I found the answer,here is the code..
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:1];
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:comps toDate:[NSDate date] options:0];
NSLog(#"new date==%#",newDate);
This will return date of the next day.
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"MMM dd, yyy"];
date = [formatter dateFromString:string];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit;
NSDateComponents *components = [calendar components:units fromDate:date];
NSInteger day = [components day];
NSInteger weekday = [components weekday]; // if necessary

Calculate NSDate for day after summertime

I just found a but in one of my apps; the problem is that I am calculating the days in a menu using initWithTimeIntervalSinceNow and adding the caculation (day*X) (X meaning the day in question).
However, the night between 27th and 28th of oct the CEST timezone will become CET thus meaning that for one day the time should be calculated by (day*X)+3600. However, I do not want to use if cases and believe there should be a better way of dealing with this.
How can I calculate future days with keeping summer/winter time in mind?
My code:
int day = (60*60*24);
NSDate *today = [NSDate date];
NSDate *days1 = [[NSDate alloc] initWithTimeIntervalSinceNow:day];
NSDate *days2 = [[NSDate alloc] initWithTimeIntervalSinceNow:(day*2)];
NSDate *days3 = [[NSDate alloc] initWithTimeIntervalSinceNow:(day*3)];
NSDate *days4 = [[NSDate alloc] initWithTimeIntervalSinceNow:(day*4)];
NSDate *days5 = [[NSDate alloc] initWithTimeIntervalSinceNow:(day*5)];
NSDate *days6 = [[NSDate alloc] initWithTimeIntervalSinceNow:(day*6)];
NSDate *days7 = [[NSDate alloc] initWithTimeIntervalSinceNow:(day*7)];
Try this:
- (NSDate *)dateByAddingXDaysFromToday:(int)days
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.day = days;
return [[NSCalendar currentCalendar] dateByAddingComponents:comps toDate:[NSDate date] options:0];
}
Then you can use:
NSDate *days1 = [self dateByAddingXDaysFromToday:1];
//etc...
It's not clear what you are trying to achieve with calculating the date objects. I'm assuming you want to create objects that refer the next seven days, same time as now.
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:1];
NSDate *now = [NSDate date];
NSDate *days1 = [calendar dateByAddingComponents:components toDate:now options:0];
NSDate *days2 = [calendar dateByAddingComponents:components toDate:days1 options:0];
NSDate *days3 = [calendar dateByAddingComponents:components toDate:days2 options:0];
....

NSCalendar and NSDateComponents returning unexpected date

I'm trying to create an NSDate from NSCalendar and NSDateComponents with:
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:[self.day intValue]];
[components setMonth:[self.month intValue]];
[components setYear:[self.year intValue]];
self.date = [calendar dateFromComponents:components];
When the day, month, year are : 9/31/2011 the NSDate is for 10/1/2011. I set the timezone for the NSCalendar after testing which didn't change the NSDate. I also tried
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
Which gave me back 9/30/2011. Anyone see an error in the way I'm calculating this?
Thanks.
Well, september 31 is really october first.
But a component has to know in which calendar to work. The following code is from apple
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:6];
[comps setMonth:5];
[comps setYear:2004];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];