将格里高利日期字符串转换为伊斯兰日期会给出正确和错误的结果

JAH*_*lia 17 calendar objective-c nsdate ios

我有以下两个日期字符串:(1)2013年 4 24日和(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]); 
Run Code Online (Sandbox Code Playgroud)

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

Converted date to Islamic = 14/06/1434这是正确的(根据所有伊斯兰国家使用的正式伊斯兰历法).但如果输入字符串是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时区,但也无济于事......

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

非常感谢.

zim*_*yan 19

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

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

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

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


小智 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]);
Run Code Online (Sandbox Code Playgroud)