Convert Date From Solar (Gregorian) to Lunar (Hijri) Using JavaScript

This article describes how to convert a date from Solar to Lunar using JavaScript.

Introduction
 

The Lunar (Hijri) calendar is very important for Muslims as is the Solar (Gregorian) calendar important because the Lunar calendar was related to some elements of worship. So I looked at many sites on the internet to understand how to calculate the age of the moon in any given day, I found many sites offering various ways and I took what I found to provide results closer to the truth.
 
 I've noticed that most sites agree on the expense of the Julian date but don't agree on how to calculate the age of the moon and found the difference between these sites to be up to one day and when the moon's age is 30 days, the result is zero in some sites.
 
 In this program I calculate the approximate age of the moon in days and did not give attention to the parts of the day of the hours and minutes.
 
 For the program to be more useful, I added a PictureBox control to display the lighted part of the moon and darkness part of the moon commensurate with the age of the moon.
 

 There is a small probability of a one-day error for any calculation to convert a date.
 
DateConverter using JavaScript 
 
 Note: You can read Months by its name or by its number.
 
 Code
  1. <!-- Test selected year if it is leap or not -->  
  2.  function CheckYear()  
  3.  {  
  4.      var y=parseInt(MyForm.SolarYearCombo.value);   
  5.      if ((y%4)==0)  
  6.      {  
  7.          if ((y%100)==0 && (y%400)!=0)  
  8.             leap=false;  
  9.          else  
  10.              leap=true;  
  11.      }  
  12.      else  
  13.          leap=false;  
  14.  }  
  15.    
  16.  <!-- Best calculation to get number approximation -->  
  17.    
  18.  function getInt(floatNum)  
  19.  {  
  20.      if (floatNum< -0.0000001)  
  21.      {  
  22.          return Math.ceil(floatNum-0.0000001);  
  23.      }  
  24.      return Math.floor(floatNum+0.0000001);  
  25.  }  
  26.    
  27.  <!-- Convert Solar (Gregorian) date to Lunar (Hijri) date -->  
  28.  function ConvertSolarToLunar(d, m, y)  
  29.  {  
  30.      var jd;  
  31.      var j, l, r;  
  32.    
  33.      if ((y>1582)||((y==1582)&&(m>10))||((y==1582)&&(m==10)&&(d>14)))   
  34.      {  
  35.          jd = getInt((1461 * (y + 4800 + getInt((m - 14) / 12))) / 4) + getInt((367 * (m - 2 - 12 * (getInt((m - 14) / 12)))) / 12) -  
  36.  getInt( (3* (getInt((y+4900+ getInt( (m-14)/12) )/100))) /4)+d-32075;  
  37.      }  
  38.      else  
  39.      {  
  40.          jd = 367 * y - getInt((7 * (y + 5001 + getInt((m - 9) / 7))) / 4) + getInt((275 * m) / 9) + d + 1729777;  
  41.      }  
  42.    
  43.      if(jd<1948440)  
  44.      {  
  45.          DateMinError();  
  46.          return;  
  47.      }  
  48.      if(jd>2621734)  
  49.      {  
  50.          DateMaxError();  
  51.          return;  
  52.      }  
  53.      theDay=jd%7;  
  54.      MyForm.thisDay.value= WeekDays[theDay];  
  55.      l=jd-1948440+10632;  
  56.      r=getInt((l-1)/10631);  
  57.      l=l-10631*r+354;  
  58.      j = (getInt((10985 - l) / 5316)) * (getInt((50 * l) / 17719)) + (getInt(l / 5670)) * (getInt((43 * l) / 15238));  
  59.      l = l - (getInt((30 - j) / 15)) * (getInt((17719 * j) / 50)) - (getInt(j / 16)) * (getInt((15238 * j) / 43)) + 29;  
  60.      m=getInt((24*l)/709);  
  61.      d=l-getInt((709*m)/24);  
  62.      y=30*r+j-30;  
  63.      MyForm.LunarDayCombo.value=d;  
  64.      MyForm.LunarMonthCombo.value=m;  
  65.      MyForm.LunarYearCombo.value=y;  
  66.  }  
  67.    
  68.  <!-- Convert Lunar (Hijri) date to Solar (Gregorian) date -->  
  69.  function ConvertLunarToSolar(d, m, y)  
  70.  {  
  71.      var jd;  
  72.      var i, j, k, l, r;  
  73.      jd = getInt((11 * y + 3) / 30) + 354 * y + 30 * m - getInt((m - 1) / 2) + d + 1948440 - 385;  
  74.      theDay=jd%7;  
  75.      MyForm.thisDay.value=WeekDays[theDay];  
  76.      if (jd > 2299160)  
  77.      {  
  78.          l=jd+68569;  
  79.          r=getInt((4*l)/146097);  
  80.          l=l-getInt((146097*r+3)/4);  
  81.          i=getInt((4000*(l+1))/1461001);  
  82.          l=l-getInt((1461*i)/4)+31;  
  83.          j=getInt((80*l)/2447);  
  84.          d=l-getInt((2447*j)/80);  
  85.          l=getInt(j/11);  
  86.          m=j+2-12*l;  
  87.          y=100*(r-49)+i+l;  
  88.      }   
  89.      else   
  90.      {  
  91.          j=jd+1402;  
  92.          k=getInt((j-1)/1461);  
  93.          l=j-1461*k;  
  94.          r=getInt((l-1)/365)-getInt(l/1461);  
  95.          i=l-365*r+30;  
  96.          j=getInt((80*i)/2447);  
  97.          d=i-getInt((2447*j)/80);  
  98.          i=getInt(j/11);  
  99.          m=j+2-12*i;  
  100.          y=4*k+r+i-4716;  
  101.      }  
  102.      MyForm.SolarDayCombo.value=d;  
  103.      MyForm.SolarMonthCombo.value=m;  
  104.      MyForm.SolarYearCombo.value=y;  
  105.  }  
  106.    
  107.  <!-- Display moon age -->  
  108.  function getAge(form)  
  109.  {  
  110.      var ag=parseInt(MyForm.LunarDayCombo.value);  
  111.      if(ag==1)  
  112.      {  
  113.          form.age.value=ag.toString()+" day";  
  114.      }  
  115.      else  
  116.      {  
  117.          form.age.value=ag.toString()+" days";  
  118.      }  
  119.      ShowMoonPhase();  
  120.  }  
  121.    
  122.  <!-- Display moon phase -->  
  123.  function ShowMoonPhase()   
  124.  {  
  125.      var ag=parseInt(MyForm.LunarDayCombo.value);  
  126.      var Phase = ag / 29.530588853;  
  127.      var Xpos;  
  128.      var Ypos;  
  129.      var Rpos;  
  130.      var Xpos1;  
  131.      var Xpos2;  
  132.      cxt.fillStyle="blue";  
  133.      cxt.fillRect(0,0,100,100);  
  134.      cxt.stroke();  
  135.      for (Ypos=0; Ypos<= 45; Ypos++)  
  136.      {  
  137.          Xpos = Math.sqrt(45*45 - Ypos*Ypos);  
  138.          // Draw darkness part of the moon  
  139.          cxt.strokeStyle = "white";  
  140.          cxt.beginPath();  
  141.          cxt.moveTo(50-Xpos, Ypos+50);  
  142.          cxt.lineTo(Xpos+50, Ypos+50);  
  143.          cxt.stroke();  
  144.          cxt.moveTo(50-Xpos, 50-Ypos);  
  145.          cxt.lineTo( Xpos+50, 50-Ypos);  
  146.          cxt.closePath();  
  147.          cxt.stroke();  
  148.          // Determine the edges of the lighted part of the moon  
  149.          Rpos = 2 * Xpos;  
  150.          if (Phase < 0.5)  
  151.          {  
  152.              Xpos1 = - Xpos;  
  153.              Xpos2 = Rpos - 2*Phase*Rpos - Xpos;  
  154.          }  
  155.          else  
  156.          {  
  157.              Xpos1 = Xpos;  
  158.              Xpos2 = Xpos - 2*Phase*Rpos + Rpos;  
  159.          }  
  160.          // Draw the lighted part of the moon  
  161.          cxt.strokeStyle = "black";  
  162.          cxt.beginPath();  
  163.          cxt.moveTo(Xpos1+50, 50-Ypos);  
  164.          cxt.lineTo(Xpos2+50, 50-Ypos);  
  165.          cxt.stroke();  
  166.          cxt.moveTo(Xpos1+50, Ypos+50);  
  167.          cxt.lineTo( Xpos2+50, Ypos+50);  
  168.          cxt.closePath();  
  169.          cxt.stroke();  
  170.      }  
  171.  } 
You can go to the source file to read the code. If you have any idea or find another code to convert the dates, please tell me.

Mostafa Kaisoun
m_kaisoun@hotmail.com