2

I would convert Gregorian date to Hijri (Islamic) date. After may search on the web, I found a source code to convert it. I converted the code from Java and PHP to C base.

The implement some times working without any problem. But some days has problem.

I need your help either fix the implement or a available code that will work without any problem! BTW I found another source code (http://emr.cs.iit.edu/~reingold/calendar.C) that is C++ base. As I don't know C++ if anyone can convert that to C Base or Objective C would be prefect (still not sure this code will work correctly or not).

P.S. You can check the correct date in: islamicfinder.org/Hcal/index.php

void gregorian_to_hijri(int* h_y, int* h_m, int* h_d, int  g_y, int  g_m, int  g_d)
{
    int year, month, day;

    int zyr;
    int zd;
    int zm;
    int zy;

    float zjd;
    int zl;
    int zn;
    int zj;

    year = g_y;
    month = g_m;
    day = g_d;


    zyr = year;
    zd = day;
    zm = month;
    zy = zyr;

    if((zy > 1582) || ((zy == 1582) && (zm > 10)) || ((zy == 1582) && (zm == 10) && (zd > 14)))
    {
        zjd = ((1461 * (zy + 4800 + ((zm - 14) / 12))) / 4)
            + ((367 * (zm - 2 - 12 * (((zm - 14) / 12)))) / 12)
            - ((3 * (((zy + 4900 + ((zm - 14) / 12)) / 100))) / 4) + zd - 32075;
    }
    else
    {
        zjd = 367 * zy - ((7 * (zy + 5001 + ((zm - 9) / 7))) / 4)
            + ((275 * zm) / 9) + zd + 1729777;
    }

    zl = zjd - 1948440 + 10632;
    zn = ((zl - 1) / 10631);
    zl = zl - 10631 * zn + 354;
    zj = (((10985 - zl) / 5316)) * ((int)((50 * zl) / 17719))
        + ((zl / 5670)) * ((int)((43 * zl) / 15238));

    zl = zl - (((30 - zj) / 15)) * (((17719 * zj) / 50))
        - ((zj / 16)) * (((15238 * zj) / 43)) + 29;

    zm = ((24 * zl) / 709);
    zd = zl - ((709 * zm) / 24);
    zy = 30 * zn + zj - 30;

    *h_y = zy;
    *h_m = zm;
    *h_d = zd;
}
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
Alish
  • 133
  • 3
  • 13

3 Answers3

10

Assuming this is for a Mac (Cocoa) or iOS (Cocoa Touch) app, since that's where you see Objective C most often, then you can just do something like this:

// Create a Gregorian Calendar
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

// Set up components of a Gregorian date
NSDateComponents *gregorianComponents = [[NSDateComponents alloc] init];

gregorianComponents.day = 4;
gregorianComponents.month = 12;
gregorianComponents.year = 2010;

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

[gregorianComponents release];
[gregorianCalendar release];


// 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", 
          [hijriComponents day],
          [hijriComponents month],
          [hijriComponents year]);

[hijriCalendar release];

If all you want is the current date, then you can skip setting up the gregorian date altogether and just do this:

// Create an Islamic calendar
NSCalendar *hijriCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSIslamicCalendar];

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

[hijriCalendar release];
Firoze Lafeer
  • 17,133
  • 4
  • 54
  • 48
  • Dear Firoze Laffer. Thanks. Fantastic example! you really did big favor. again thanks for your help! – Alish Dec 05 '10 at 06:06
  • 2
    Just one problem with it! I'm sure NSIslamicCalendar have a problem! if you test 7/12/2010 with NSIslamicCivilCalendar == 30/12/1431 and if you test the date with NSIslamicCalendar == 2/1/1432. However the correct date is: 1/1/1432!... Still have same problem with my code! – Alish Dec 05 '10 at 06:10
  • Hmm, that is interesting that it is one day off. Maybe post a bug report with Apple. As a temporary workaround, you could of course just add one day to the gregorian date before converting. – Firoze Lafeer Dec 05 '10 at 06:38
  • That was only example! You can find many problem in this year! I think in 1432 70% of result are wrong! – Alish Dec 05 '10 at 06:46
  • Can you list other examples? Perhaps there is a pattern. Also, is the other code you found consistent? Do they all produce the same dates? (other than Apple's) – Firoze Lafeer Dec 05 '10 at 06:54
  • yes I will. Unfortunately Apple is not the only one! All the codes I check have this problem. And interesting part is no one solve the issue! and apparently no one cares! But site such as http://www.islamicfinder.org/Hcal/index.php doesn't have any problem! – Alish Dec 05 '10 at 07:07
  • 1
    2011/3/5 == 1432/3/30 however with NSIslamicCalendar: 1443/3/30 2011/3/6 == 1432/4/1 however with NSIslamicCalendar: 1443/4/2 2011/4/4 == 1432/4/30 however with NSIslamicCalendar: 1443/5/1 2011/4/5 == 1432/5/1 however with NSIslamicCalendar: 1443/5/2 Also in middle of all the all dates with be mixed up! Also you can check more date with small implement. Many more you can find. – Alish Dec 05 '10 at 09:17
1

Have a look at this topic: how to convert hijari date into gregorian date in java script?

The question mentions JavaScript but the top answer seems to have links to implementations in a variety of languages.

Community
  • 1
  • 1
mpenkov
  • 21,621
  • 10
  • 84
  • 126
1

You should be able to do this in Objective-C (if that really is an option) using NSCalendar.

Wevah
  • 28,182
  • 7
  • 83
  • 72