Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding year component to islamic calendar fails

Following code shows the problem: Advancing a full year from the first day of the year 1435 does not result in the first day of 1436.

Any ideas what i'm missing?

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:1];
[components setMonth:1];
[components setYear:1435];


NSCalendar *islamic = [[NSCalendar alloc] initWithCalendarIdentifier:NSIslamicCalendar];
NSDate *date = [islamic dateFromComponents:components];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setCalendar:islamic];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];

NSLog(@"%@", [dateFormatter stringFromDate:date]);  // -> 01.01.1435

NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setYear:1];

NSDate *dateWithOffset = [islamic dateByAddingComponents:offsetComponents toDate:date options:0];

NSLog(@"%@", [dateFormatter stringFromDate:dateWithOffset]); 
// -> 30.12.1435 ... WHY NOT 01.01.1436 ????
like image 279
Frank Martin Avatar asked Jun 05 '12 13:06

Frank Martin


1 Answers

My suspicion is because of summertime/wintertime (daylight savings time) difference. Muh. 1, 1435 falls on November 5, 2013, while Muh. 1, 1436 falls on October 25, 2014. The first date is during wintertime, the second during summertime.

The first NSDate you created is exactly November 5, 2013 00:00 (at midnight). "dateByAddingComponents:" works by converting the components to seconds, and adding that to the first date. In this case, the result is October 24, 2014 23:00, because of the summertime.

This would also mean that the results could be different for different people around the world because of daylight saving time differences between timezones.

You can prevent the problem by setting the first date to mid-day, instead of midnight (which is in general a good idea when working with pure dates):

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:1];
[components setMonth:1];
[components setYear:1435];
[components setHour:12];

Now, whether this is correct behaviour of "dateByAddingComponents" is another question.

like image 107
fishinear Avatar answered Sep 28 '22 03:09

fishinear