17

我有以下两个日期字符串:(1)24/04/2013和(2)19/03/2013我正在尝试将这些日期转换为伊斯兰(Um Al Qura)日期,我正在使用此代码块这样做:

    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.dateFormat = @"dd/MM/yyyy";
    df.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDate *dateInGrogrian = [df dateFromString:@"24/04/2013"];

    NSDateFormatter *df2 = [[NSDateFormatter alloc] init];
    NSCalendar * cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSIslamicCalendar];
    [df2 setCalendar:cal];
    [df2 setDateFormat:@"dd/MM/yyyy"];
    NSLog(@"Converted date to Islamic = %@",[df2 stringFromDate:dateInGrogrian]); 

如果输入字符串是 24/04/2013,则NSLog显示:

Converted date to Islamic = 14/06/1434这是正确的(根据所有伊斯兰国家使用的正式伊斯兰日历)。但如果输入字符串是 19/03/2013,则NSLog显示:

Converted date to Islamic = 08/05/1434这是不正确的(根据伊斯兰日历,正确的日期必须是 1434 年 7 月 5 日,晚了 1 天)。

-在您提出答案之前要考虑的注意事项:

(1)我曾尝试使用日历标识符NSIslamicCivilCalendar而不是NSIslamicCalendar,但无济于事:转换后的日期之一是正确的,另一个是错误的(晚 1 天)。

(2)我曾尝试像这样使用 GMT 时区:[df2 setTimeZone : [NSTimeZone timeZoneWithName:@"GMT"]];,这为第 (2) 天生成了正确的转换日期,但对于第 (1) 天不正确(落后 1 天)。

(3)我尝试过组合解决方案:NSIslamicCivilCalendar有/无 GMT 时区,NSIslamicCalendar有/无 GMT 时区,但也无济于事......

任何人都可以提供满足两个日期的代码块吗?所以我确保任何提供的公历日期字符串都正确转换为伊斯兰日期字符串。

太感谢了。

4

2 回答 2

19

在打印出过去 4 年的所有日期之后,Apple 似乎使用了一种在数学上计算伊斯兰历法的公认公式,因为正如 Moxy 指出的那样,实际的历法不是基于科学日,而是基于月球的近似值。

这个公式是所有奇数月份有 30 天,所有偶数月份有 29 天,并且在任何年份 mod 30 为以下之一的年份的最后一个月添加额外的一天:2、5、7、 10、13、16、18、21、24、26 或 29。

结果是平均月长为 29.53056 天,非常接近 29.53059 天的农历月份。

该公式已在计算机的其他地方使用,因为它是唯一一种无需使用历史上每一年的查找表即可计算日期的方法。因此,除非您自己编写查找表,否则对于所有向后和向前的日期,这将尽可能准确。

于 2013-05-02T22:42:42.070 回答
8
// Create a Gregorian Calendar
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

// Set up components of a Gregorian date
NSDateComponents *gregorianComponents = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];

NSLog(@"[In Gregorian calendar ->] Day: %ld, Month: %ld, Year:%ld",
      (long)[gregorianComponents day],
      (long)[gregorianComponents month],
      (long)[gregorianComponents year]);


gregorianComponents.day = [gregorianComponents day];
gregorianComponents.month = [gregorianComponents month];
gregorianComponents.year = [gregorianComponents year];

// Create the date
NSDate *date = [gregorianCalendar dateFromComponents:gregorianComponents];



// Then create an Islamic calendar
NSCalendar *hijriCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSIslamicCivilCalendar];

// And grab those date components for the same date
NSDateComponents *hijriComponents = [hijriCalendar components:(NSDayCalendarUnit |
                                                               NSMonthCalendarUnit |
                                                               NSYearCalendarUnit)
                                                     fromDate:date];


NSLog(@"[In Hijri calendar ->] Day: %ld, Month: %ld, Year:%ld",
      (long)[hijriComponents day],
      (long)[hijriComponents month],
      (long)[hijriComponents year]);
于 2013-06-18T06:22:25.253 回答