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];
....
Related
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.
Suppose i have two parameters
Australia/Sydney (GMT+10) offset 36000 &
Asia/Kolkata (IST) offset 19800
as timezones, it gives different values for the day component of current day itself. I am not able to figure out what am i doing wrong.. :( A little clue will be appreciated
-(NSInteger)getDayWithTimeZoneName:(NSString *)timeZoneName{
// Instantiate a timezone
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:timeZoneName];
//Instantiate a date formatter
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setLocale:[NSLocale currentLocale]];
[df setTimeZone:timeZone];
[df setDateFormat:#"yyyy-MM-dd"];
NSString *dateStr = [df stringFromDate:[NSDate date]];
NSDate *date = [df dateFromString:dateStr];
// NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay fromDate:date];
NSDateComponents *components = [[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]components:NSDayCalendarUnit fromDate:date];
NSInteger day = [components day];
NSLog(#"Date component for timeZone %# is %ld", timeZoneName,(long)day);
return day;
}
NSFormatter isn't designed to convert or calculate dates:
NSString *dateStr = [df stringFromDate:[NSDate date]];
dateStr is the date in Sydney (2016-05-16 0:00).
NSDate *date = [df dateFromString:dateStr];
date is GMT, 10 hours behind Sydney (2016-05-15 14:00).
Use NSCalendar to calculate dates:
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = timeZone;
NSDateComponents *components = [calendar components:NSCalendarUnitDay fromDate:[NSDate date]];
NSInteger day = [components day];
I have a datepicker and I want to have just one row with 3 options: current day, one day after and one day before .
Would you help me to do that?
My question is, how can I add 'current day' with one day after and one day before ?
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:days];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *end = [gregorian dateByAddingComponents:components toDate:[NSDate date] options:0];
Where days is an integer representing the days you want to add/subtract from the current day.
This is how i did-
-(void)getDate{
NSString *str_CurDate =[self getCurrentDate];
NSString *str_NextDay =[self getFormattedDate:[self dateByAddingDays:1]];
NSString *str_PrevDay =[self getFormattedDate:[self dateByAddingDays:-1]];
}
Now implement these method
-(NSString*)getCurrentDate{
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"d/M/yyyy"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
return dateString;
}
- (NSDate *) dateByAddingDays:(int)days {
NSDate *retVal;
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:days];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
retVal= [gregorian dateByAddingComponents:components toDate:[NSDate date] options:0];
return retVal;
}
-(NSString*)getFormattedDate:(NSDate*)myDate{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"d/M/yyyy"];
NSString *dateString = [dateFormatter stringFromDate:myDate];
return dateString;
}
Encapsulate in a category on NSDate
- (NSDate *) dateByAddingDays:(int)days {
NSDate *retVal;
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:days];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
retVal = [gregorian dateByAddingComponents:components toDate:self options:0];
return retVal;
}
How can I get a past date in objective C? Like,
NSDate *pastDate = //some date 2 weeks ago
Off of top of my head:
NSDate *today = [NSDate date];
NSDateComponents *dc = [[[NSDateComponents alloc] init] autorelease];
[dc setDay:-14];
NSCalendar *cal = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDate *pastDate = [cal dateByAddingComponents:dc toDate:today options:0];
NSDate *today = [NSDate date];
NSLog(#"today: %#",today);
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setWeek:-2];
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDate *pastDate = [currentCalendar dateByAddingComponents:dateComponents toDate:today options:0];
NSLog(#"pastDate: %#",pastDate);
NSLog output:
today: 2011-12-07 11:52:15 +0000
pastDate: 2011-11-23 11:52:15 +0000
This example used ARC.
Assume you don't care about DST,
NSDate* pastDate = [NSDate dateWithTimeIntervalSinceNow:-2*7*24*60*60];
// Get the date which is exactly 2 weeks (14 days) ago.
NSDate *now = [[NSDate alloc] init];
gives the current date.
However if the phone calendar is not Gregorian (on the emulator there is also Japanese and Buddhist), the current date will not be Gregorian.
The question now is how to convert to a Gregorian date or make sure it will be in the Gregorian format from the beginning. This is crucial for some server communication.
Thank you!
NSDate just represents a point in time and has no format in itself.
To format an NSDate to e.g. a string, you should use NSDateFormatter. It has a calendar property, and if you set this property to an instance of a Gregorian calendar, the outputted format will match a Gregorian style.
NSDate *now = [NSDate date];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setCalendar:gregorianCalendar];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];
NSString *formattedDate = [formatter stringFromDate:now];
NSLog(#"%#", formattedDate);
[gregorianCalendar release];
[formatter release];
The picked answer actually I can't compare them. only display is not enough for my project.
I finally come up with a solution that covert (NSDate) currentDate -> gregorianDate
then we can compare those NSDates.
Just remember that the NSDates should be used temporary .(it do not attach with any calendar)
NSDate* currentDate = [NSDate date];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *gregorianComponents = [gregorianCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:currentDate];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:[gregorianComponents day]];
[comps setMonth:[gregorianComponents month]];
[comps setYear:[gregorianComponents year]];
[comps setHour:[gregorianComponents hour]];
[comps setMinute:[gregorianComponents minute]];
[comps setSecond:[gregorianComponents second]];
NSCalendar *currentCalendar = [NSCalendar autoupdatingCurrentCalendar];
NSDate *today = [currentCalendar dateFromComponents:comps];