Преобразование gregorian строки даты в исламскую дату дает правильные и неправильные результаты
У меня есть следующие две строки даты: (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
, который является неправильным (согласно исламскому календарю, правильная дата должна быть 07/05/1434, которая на 1 день позади).
- Примечания для рассмотрения, прежде чем вы предлагаете ответ:
(1) Я попытался использовать идентификатор календаря NSIslamicCivilCalendar
вместо NSIslamicCalendar
, но безрезультатно: одна из преобразованных дат была правильной, а другая была неправильной (1 день сзади).
(2) Я попытался использовать часовой пояс GMT следующим образом: [df2 setTimeZone : [NSTimeZone timeZoneWithName:@"GMT"]];
, это привело к правильной конвертированной дате для дня (2), но неверно для дня (1) (1 день позади).
(3) Я пробовал комбинации решений: NSIslamicCivilCalendar
с/без часовой пояс GMT, NSIslamicCalendar
с/без часовой пояс, но также безрезультатно...
может ли кто-нибудь предоставить блок кода, который удовлетворяет обеим датам? поэтому я гарантирую, что любая предоставленная gregorian строка даты правильно преобразована в исламскую строку даты.
Большое вам спасибо.
Ответы
Ответ 1
После распечатки всех дат за последние 4 года кажется, что Apple использует несколько принятую формулу для математического расчета Исламского календаря, поскольку, как указал Мокси, фактический календарь не основан на научных днях, а вместо этого лунное приближение,
Эта формула состоит в том, что все нечетные месяцы имеют 30 дней, а все четные месяцы - 29 дней, причем дополнительный день добавляется к последнему месяцу в течение любого года, в течение которого год 30-го года является одним из следующих: 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 или 29.
В результате получается средняя длина месяца 29.53056 дней, что довольно близко к лунному месяцу 29.53059 дней.
Эта формула используется в других местах на компьютерах, так как это единственный метод для расчета даты без использования таблицы поиска для каждого года в истории. Таким образом, если вы сами не напишите справочную таблицу, это будет так же точно, как вы можете получить для всех дат, идущих назад и вперед.
Ответ 2
// 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]);