Do I understand NSHebrewCalendar correctly?

I ran a quick test using Cocoa Touch to see how NSHebrewCalendar works. I am particularly interested in the numbers of the month. I used the date to easily change dates, and I passed it to a method that records the Hebrew date, Hebrew month number, Hebrew year, and if the year is a leap year. It looks like this:

BOOL isHebrewLeapYear = [self.calendar isHebrewLeapYear:[calendar hebrewYearForDate:[self.calendar workingDate]]]; NSLog(@"Hebrew Date:%@, Month Number: %i, %i is Leap Year: %i", [self.calendar stringFromHebrewDate:[self.calendar workingDate]], [self.calendar hebrewMonthNumberFromDate:[self.calendar workingDate]], [calendar hebrewYearForDate:[self.calendar workingDate]], isHebrewLeapYear); 

The self.calendar object is a custom class. The workingDate property is an instance of NSDate . Here are the relevant method declarations.

 // Check if a given year is a leap year - (BOOL) isHebrewLeapYear:(NSInteger)year{ return ((7 * year + 1) % 19) < 7; } //Get the hebrew year for a given date - (NSInteger) hebrewYearForDate:(NSDate *)date{ NSCalendar *hebrewCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar] autorelease]; return [[hebrewCalendar components:NSYearCalendarUnit fromDate:date] year]; } - (NSInteger) hebrewMonthNumberFromDate:(NSDate *)date{ NSCalendar *hebrewCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar] autorelease]; return [[hebrewCalendar components:NSMonthCalendarUnit fromDate:date] month]; } 

Apparently, summer leap years are handled as follows:

  • Numbering of the month begins with 1, and this month "Tishri".
  • During the non-wood year, Adar is 7, not 6.
  • In the leap year of Adar, I am number 6, and Adar II is number 7.
  • Nisan is always 8, etc. to "Elul", which is always 13.

Does my experiment give accurate results? Is this behavior documented anywhere?

+4
source share
2 answers

Monthly numbering starts at 1, and this month "Tishri."

Right.

During the non-wood year, Adar is month number 7, not 6.

Technically incorrect. (More on this below)

In the leap year of Adar, I am number 6, and Adar II is number 7.

Right.

β€œNisan” is always 8, and so on to β€œElul,” which is always 13.

Right.

So what about Adar in a non-leap year? I ran this code to find out:

 @autoreleasepool { NSDate *today = [NSDate date]; NSCalendar *hebrew = [[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar]; NSDateComponents *diff = [[NSDateComponents alloc] init]; NSDateFormatter *f = [[NSDateFormatter alloc] init]; [f setDateFormat:@"d MMMM y"]; [f setCalendar:hebrew]; for (NSInteger i = 0; i < 19; ++i) { NSDateComponents *comp = [[NSDateComponents alloc] init]; [comp setYear:5772 + i]; [comp setDay:1]; NSLog(@"============= %d ============", [comp year]); for (NSInteger i = 1; i <= 13; ++i) { [comp setMonth:i]; NSDate *d = [hebrew dateFromComponents:comp]; NSLog(@"%d: %@ (%@)", i, [f stringFromDate:d], d); } } } 

In a leap year, this will record what you expect:

 ============= 5790 ============ 1: 1 Tishri 5790 (2029-09-10 07:00:00 +0000) 2: 1 Heshvan 5790 (2029-10-10 07:00:00 +0000) 3: 1 Kislev 5790 (2029-11-08 08:00:00 +0000) 4: 1 Tevet 5790 (2029-12-07 08:00:00 +0000) 5: 1 Shevat 5790 (2030-01-05 08:00:00 +0000) 6: 1 Adar I 5790 (2030-02-04 08:00:00 +0000) 7: 1 Adar II 5790 (2030-03-06 08:00:00 +0000) 8: 1 Nisan 5790 (2030-04-04 07:00:00 +0000) 9: 1 Iyar 5790 (2030-05-04 07:00:00 +0000) 10: 1 Sivan 5790 (2030-06-02 07:00:00 +0000) 11: 1 Tamuz 5790 (2030-07-02 07:00:00 +0000) 12: 1 Av 5790 (2030-07-31 07:00:00 +0000) 13: 1 Elul 5790 (2030-08-30 07:00:00 +0000) 

For each increment of the month component, we get a different date. But when we run this in a non-leap year, we get the following:

 ============= 5789 ============ 1: 1 Tishri 5789 (2028-09-21 07:00:00 +0000) 2: 1 Heshvan 5789 (2028-10-21 07:00:00 +0000) 3: 1 Kislev 5789 (2028-11-19 08:00:00 +0000) 4: 1 Tevet 5789 (2028-12-19 08:00:00 +0000) 5: 1 Shevat 5789 (2029-01-17 08:00:00 +0000) 6: 1 Adar 5789 (2029-02-16 08:00:00 +0000) 7: 1 Adar 5789 (2029-02-16 08:00:00 +0000) 8: 1 Nisan 5789 (2029-03-17 07:00:00 +0000) 9: 1 Iyar 5789 (2029-04-16 07:00:00 +0000) 10: 1 Sivan 5789 (2029-05-15 07:00:00 +0000) 11: 1 Tamuz 5789 (2029-06-14 07:00:00 +0000) 12: 1 Av 5789 (2029-07-13 07:00:00 +0000) 13: 1 Elul 5789 (2029-08-12 07:00:00 +0000) 

Here we see that the months 6 and 7 will be evaluated by Adar. Thus, Adar is both the sixth and seventh month in off-peak years.


In addition, since we know that year 5790 is a leap year, we can derive a simpler implementation of the -isHebrewLeapYear: method:

 - (BOOL) isHebrewLeapYear:(NSInteger)year{ return year % 19 == 14; } 

Strike>

+3
source

To avoid my own calculations when there was a leap year, here is the code that I used to check (based on the previous conclusion that 6 and 7 months are Adar I for a normal year:

 - (BOOL)isRegularYear:(NSDate *)date { NSCalendar *hebrew = [[NSCalendar alloc] initWithCalendarIdentifier:NSHebrewCalendar]; NSDateComponents *comp = [hebrew components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date]; [comp setMonth:6]; NSDate *adar_i = [hebrew dateFromComponents:comp]; [comp setMonth:7]; NSDate *adar_ii = [hebrew dateFromComponents:comp]; return [adar_i isEqualToDate:adar_ii]; } 
0
source

Source: https://habr.com/ru/post/1382099/


All Articles