11

I have work on many projects with date converts. for example, I work on the solar calendar and how to convert them to Gregorian dates and vice versa. The solar calendar (Persian calendar) is almost similar to the Gregorian date in terms of the number of days in a year[leap or not].
But I recently worked on a project with the lunar calendar. As I research on the Lunar calendar, I realized that there isn't any single logical method to convert the lunar system to solar(at least as far as I know).
Here are some references links that I researched on them:

  1. Cannot convert from Hijri Date to Gregorian date (c#)
  2. Convert date from Hijri Calendar to Gregorian Calendar and vise versa
  3. Hijri Date To gregorian using DateTime.Parse
  4. Convert Hijri date to Gregorian dat

As I followed the above links, training, and testing people presented algorithms, I noticed that none of them are absolutely correct.

Suffice it to say, just Convert "1441/02/30" [Safar 30th] to Gregorian date which every method that you want to try.

The following image is helpful for the aforementioned example. enter image description here

I put here my some test codes and fails:

CultureInfo arSA = new CultureInfo("ar-SA");
arSA.DateTimeFormat.Calendar = new HijriCalendar();
var dateValue = DateTime.ParseExact("1441/02/30", "yyyy/MM/dd", arSA);
return dateValue.ToString();

The error for above Code:

The DateTime represented by the string is not supported in calendar System.Globalization.HijriCalendar.

HijriCalendar hc = new HijriCalendar();
DateTime date = new DateTime(1441, 2, 30, hc);
return date.ToString();

The error for above Code:

"Day must be between 1 and 29 for month 2."

string hijri = "1441/2/30";
HijriCalendar hc = new HijriCalendar();
int year = int.Parse(hijri.Substring(0, 4));
string rem = hijri.Remove(0, 5);
int end = rem.IndexOf('/', 0);
int month = int.Parse(rem.Substring(0, end));
rem = rem.Remove(0, end + 1);
int day = int.Parse(rem);
DateTime date = new DateTime(year, month, day, hc);
return date.ToShortDateString();

The error for above Code:

"Day must be between 1 and 29 for month 2."

After that, I was trying to understand that is there any algorithm to deploying the convert Hijri date to Gregorian date?
So I test some Islamic online date converter and I got surprised!
Just try to enter "1441/2/30" on both date convertors.
the first one returning October 30, 2019
And the second one returning 29 October 2019
Hijri gregorian-converter
Islamic Date Converter - Gregorian Calendar Converter

So I don't know is there any real algorithm to convert Hijri dates to Gregorian .
Thanks in advance for your time.

For more info, https://www.wikiwand.com/simple/Islamic_calendar


Update: I know there isn't any correct library for know. but if someone has knowledge or details about Hijri Calendar (all its interface) please just describe here I really want to deploy a Hijri calendar for all.

Reza Paidar
  • 863
  • 4
  • 21
  • 51
  • should your example give output as 17-October-2019 ? – Soner from The Ottoman Empire Jan 14 '20 at 12:03
  • When you try your example on https://www.searchtruth.com/hijri/, it results in wrong date ?? – Soner from The Ottoman Empire Jan 14 '20 at 12:05
  • I really don't know what is the correct output, due to two Islamic date convertor that i mentioned in my post, the output should be `October 30, 2019 wed` or `October 29, 2019 tue`. I tried now. – Reza Paidar Jan 14 '20 at 12:07
  • your input date seems wrong. If you get in 1441 instead of 1442 for 30th safer. Check your date's correctness. – Soner from The Ottoman Empire Jan 14 '20 at 12:08
  • Nope, the same error for all methods that I have. How could be the input is incorrect? in 1441(equal to 2019-2020) Safar has 30 days. – Reza Paidar Jan 14 '20 at 12:11
  • Try hijri to georgian convertors online to see the results before coding! – Soner from The Ottoman Empire Jan 14 '20 at 12:13
  • I replace 1441 to 1442 and get different answers because the lunar calendar has 11 - 12 days lesser than the solar calendar. so it's understandable why the answer is different for each year. – Reza Paidar Jan 14 '20 at 12:16
  • According to https://learn.microsoft.com/en-us/dotnet/api/system.globalization.hijricalendar?view=netframework-4.8 (the C# HijriCalendar implementation, 02 (Safar) only has 29 days – Gus Jan 14 '20 at 12:26
  • @Gus: I don't know what I must to say, I noticed that before the Safar has 29 days and sometimes 30 days (irrelevant to the leap year) in some Islamic calendar. for example, you can just see and try by yourself that some Arabic month has 30 days or 29. But it Microsoft reference the order is different. – Reza Paidar Jan 14 '20 at 12:39
  • Different representations of the Islamic calendar have different leap year patterns (and different epochs). Do you know which particular one you're interested in? – Jon Skeet Jan 14 '20 at 13:47
  • no sorry, I don't know how many exist of them, and each reference shows its output without any description or name. – Reza Paidar Jan 14 '20 at 13:52
  • Note that there are certainly Islamic calendar representations where Safar in 1441 *does* have only 29 days, e.g. https://habibur.com/hijri/1441/ – Jon Skeet Jan 14 '20 at 13:52
  • So why the other says Safar has 30? This project is for an Iraqi company and they believe that this year Safar has 30 days. I'm very confused. how possible a calender has multiple interfaces? they even have an anniversary on every Safar 30th!!! – Reza Paidar Jan 14 '20 at 13:57
  • Oh, maybe you should be using the PersianCalendar then (https://learn.microsoft.com/en-us/dotnet/api/system.globalization.persiancalendar?view=netframework-4.8) – Gus Jan 14 '20 at 14:10
  • 1
    @Gus: Persian calendar is using to the solar system and invented by `Omar khayyam` the Persian mathematician. Persian calendar has 365 days(366 in a leap year) but Lunar calender is 11-12 days lesser than the Persian calendar. – Reza Paidar Jan 14 '20 at 14:21

1 Answers1

1

You can use something like this code to convert and parse hijri calendar strings to gregorian DateTime.

//assuming current culture is like en-us or something with gregorian calendar
string hijri = "1441/2/30";
HijriCalendar hc = new HijriCalendar();
var dateParts = hijri.Split('/');
DateTime? gregorianDate=null;
if (dateParts.Length == 3 && int.TryParse(dateParts[0], out int year) &&
     int.TryParse(dateParts[1], out int month) && int.TryParse(dateParts[2], out int day))
{
      if(month == 2 && day==30)
      {
         var temp = hc.ToDateTime(year, month, 29, 0, 0, 0, 0);
         gregorianDate = temp.AddDays(1);
      }
      else
      {
         gregorianDate = hc.ToDateTime(year, month, day, 0, 0, 0, 0);
      }

}
Ali Hamidi
  • 61
  • 1
  • 2
  • 5
  • thanks for your giving time and your solution. But I already test your solution and it throws an error `Day must be between 1 and 29 for month 2. Parameter name: day`. As we argued before in my post comments, The Safar of another Hijri(lunar) month has variable days count. your solution has the same error similar to other solutions. – Reza Paidar Jan 14 '20 at 16:22
  • May be there is a bug in the **HijriCalendar** Class of .Net so I edited the code and it has a workaround for the exception. – Ali Hamidi Jan 14 '20 at 17:15
  • Thanks. I can't say that there is bug with .net liberary in this case. I noticed that there are more than one interfaces are epoches with hijri calander without any logical description. Your solution is a cheat to skip error not a quite and accurate answer. However i will vote u up for giving time – Reza Paidar Jan 14 '20 at 17:49
  • 1
    I have seen the source Code of **HijriCalendar** Class. it is checking DaysInMonth before converting the dates. It assumes 29 days for **Safar** (month 2). So It has a small bug for this month – Ali Hamidi Jan 14 '20 at 18:03
  • 1
    If you check on comments on my post, microsoft introduced documentation for hijri calendar and you can found out there Safar and other month has staticly 29 days. So In some way you are right this is a bug for this library. – Reza Paidar Jan 14 '20 at 18:15