2011-11-20 69 views
4

我使用Cocoa Touch進行了一次快速測試,以瞭解NSHebrewCalendar的工作原理。我對月份數字特別感興趣。我使用日期選擇器輕鬆更改日期,並將其傳遞給記錄希伯來語日期,希伯來語月數,希伯來語年以及年度是閏年的方法。看起來像這樣:我是否正確理解NSHebrewCalendar?

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);  

self.calendar object是一個自定義類。 workingDate屬性是一個NSDate實例。這裏是相關的方法聲明。

  • 月編號起始於1,與月被「提市黎月」:

    // 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]; 
    } 
    

    顯然希伯來語閏年如下的處理。

  • 在nonleap年,亞達是月7號,而不是6
  • 在閏年,亞達我是6號和亞達II是7
  • 「尼散月」始終是8,以此類推,直到「 Elul「,它總是13.

這聽起來像我的實驗產生準確的結果嗎?這種行爲是否在任何地方記錄?

回答

3

月份編號從1開始,當月爲「Tishri」。

正確。

在nonleap年,亞達是月7號,而不是6

技術上不正確。 (更多關於該下文)

在閏年,亞達我是6號和亞達II是7

正確的。

「尼森」 始終是8,等等,直到 「以祿」,這始終是13.

正確。

那麼Adar在非閏年有什麼用?我跑這個代碼,找出:

@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); 
     } 
    } 

} 

在一個閏年,這將記錄你所期望的:

============= 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) 

對於「月」日期組件的每個增量,我們得到了一個不同日期。但是,當我們在非閏年運行此,我們得到這樣的:

============= 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) 

在這裏,我們看到,有6 7將一個月都評估爲亞達。因此,亞達爾是非閏年的第六和第七個月。


另外,因爲我們知道,今年5790是閏年,我們可以推導出一個簡單的實現了 -isHebrewLeapYear:方法:

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

+0

感謝您的詳細解答!我不知道你對「isHebrewLeapYear」的簡化是正確的,因爲在19年的週期中有幾個閏年。 (這可能是因爲你正在與現代以色列日曆一起工作,而且我正在與傳統/聖經的日曆一起工作;我不知道足以告訴你這一點。) – Moshe

+0

@Moshe哎呀,你是對的!我忘記每個週期有7個閏年;我在想只有一個。 –

+0

我意識到這個職位是幾歲。但是,我想指出一些事情。在閏年,它是第一個Adar是閏月,Adar I.第二個月是Adar。現在我想弄清楚的是,當你有什麼是日期組件時,生成Adar II的最有效方法是什麼。如果你只是使用月份來索引月份數組,你會得到Adar,而不是Adar II。也許它會使用日期格式化程序,就像上面那樣,但是你需要一個日期而不是日期組件。 –

0

爲了避免使我自己計算閏年的時間,下面是我用來測試它的代碼(根據以前的發現,該月份是在一個正常年份的Adar I:

- (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]; 
}