将格里高利日期字符串转换为伊斯兰日期可以得到正确的&结果不正确

时间:2013-04-24 14:35:12

标签: ios objective-c calendar nsdate

我有以下两个日期字符串:(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这是正确的(根据所有伊斯兰国家使用的the formal Islamic calendar)。但如果输入字符串是19/03/2013,NSLog显示:

Converted date to Islamic = 08/05/1434这是不正确的(根据伊斯兰日历,正确的日期必须是07/05/1434,落后1天)。

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

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

(2)我曾尝试使用这样的GMT时区:[df2 setTimeZone : [NSTimeZone timeZoneWithName:@"GMT"]];,这会产生第(2)天的正确转换日期,但第(1)天不正确(1)一天后面。)

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

任何人都可以提供满足两个日期的代码块吗?所以我确保任何提供的格里高利日期字符串都正确地转换成伊斯兰日期字符串。

非常感谢你。

2 个答案:

答案 0 :(得分:18)

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

这个公式是所有奇数月份都有30天,所有偶数月份都有29天,在任何一年的最后一个月加上额外的一天,其中年份mod 30是以下之一:2,5 ,7,10,13,16,18,21,24,26或29.

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

此公式已在计算机的其他地方使用,因为它是唯一一种在历史记录中不使用查找表来计算日期的方法。因此,除非您自己编写查找表,否则这将与您可以获得的所有日期前后准确一样准确。

答案 1 :(得分: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]);