1
votes

Following is my code:

NSDateComponents *componenetsForEnd = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:endDate];
NSInteger endDay = [componenetsForEnd day];
NSInteger endMonth = [componenetsFoeEnd month];
NSInteger endDayValue = componenetsForEnd.weekday;

Now: when endDate = 2015-08-31 23:59:59 +0000, I am getting month as 9! This is causing wrong endDayValue. What is going wrong here?

EDIT:

Here is how I calculate endDate :

NSDate *endDate = [self endOfMonthForDate:todayDate];

this method takes today's date with [NSDate date] and this is how it goes:

- (NSDate *) dateByAddingMonths: (NSInteger) monthsToAdd andDate: (NSDate *)date
{
NSCalendar * calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDateComponents * months = [[NSDateComponents alloc] init];
[months setMonth: monthsToAdd];

return [calendar dateByAddingComponents: months toDate: date options: 0];
}

- (NSDate *) endOfMonthForDate: (NSDate *)date
{
NSCalendar * calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];

NSDate * plusOneMonthDate = [self dateByAddingMonths: 1 andDate:date];


NSDateComponents * plusOneMonthDateComponents = [calendar components: NSYearCalendarUnit | NSMonthCalendarUnit fromDate: plusOneMonthDate];

NSDate * endOfMonth1 = [[calendar dateFromComponents: plusOneMonthDateComponents] dateByAddingTimeInterval: -1]; // One second before the start of next month
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];

NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:endOfMonth1];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:endOfMonth1];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* endOfMonth = [[NSDate alloc] initWithTimeInterval:interval sinceDate:endOfMonth1];

return endOfMonth;
}

Also tried performing these actions to make NSDateComponents and NSDate with dateFormatter in systemTimeZone:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *endDateString = [dateFormatter stringFromDate:endDate];

NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc]init];
[dateFormatter2 setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter2.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *endDateProper = [dateFormatter2 dateFromString:endDateString];

NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *componenetsForEnd = [greCalendar components:NSWeekdayCalendarUnit | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:endDateProper];
[componenetsForEnd setTimeZone:[NSTimeZone systemTimeZone]];
2
Are time zones in you calendar and date object same? I can see that date is UTC. If your calendar uses UTC+ you will get next day, and in this particular example it's also a next month.XeNoN
how to check timezone in calendar?tech savvy
[NSCalendar currentCalendar].timeZoneXeNoN

2 Answers

0
votes

Instead of using current calendar

[NSCalendar currentCalendar]

you can use:

NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

0
votes

The problem was with the fact that I think is this way: When calculating a day, month or Hour, minute and second , you need to specify that timezone for dateComponents is UTC i.e. GMT. However, my endDateProper which is in system timezone.

So, doing this did the trick for me:

NSDateComponents *componenetsForEnd = [greCalendar componentsInTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"] fromDate:endDateProper];