Lunar calendar in C#



Lunar calendar is very important for Muslims such as the importance of solar calendar because lunar calendar was related to some elements of worship, so I looked at many sites on the internet to know how to calculate the age of the moon in any given day, I found many sites offer different ways, I took what I found to give results closer to the truth.

I've noticed that most sites agree on the expense of the Julian date but don't agree to calculate the age of the moon, and found the difference between these sites 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.

In order for the program would be more useful, I add PictureBox control to display the lighted part of the moon and darkness part of the moon commensurate with the age of the moon.

I create a project under C# (2003) , the MoonPhase project has one form (frmMoon) with following controls:
  • MonthCalendar control (MyCalendar).
  • Button control (btnToDay).
  • Button control (btnClose).
  • PictureBox control (PicMoon).
  • Label control (lblAge).
About the Code

Convert date to Julian date:

private int JulianDate(int d, int m, int y)
    int mm, yy;
    int k1, k2, k3;
    int j;
    yy = y - (int)((12 - m) / 10);
    mm = m + 9;
    if (mm >= 12)
        mm = mm - 12;
    k1 = (int)(365.25 * (yy + 4712));
    k2 = (int)(30.6001 * mm + 0.5);
    k3 = (int)((int)((yy / 100) + 49) * 0.75) - 38;
    // 'j' for dates in Julian calendar:
    j = k1 + k2 + d + 59;
    if (j > 2299160)
        // For Gregorian calendar:
        j = j - k3;  // 'j' is the Julian date at 12h UT (Universal Time)
    return j;

Calculate the approximate moon's age in days:

private double MoonAge(int d, int m, int y)
    int j = JulianDate(d, m, y);
    //Calculate the approximate phase of the moon
    ip = (j + 4.867) / 29.53059;
    ip = ip - Math.Floor(ip);
    //After several trials I've seen to add the following lines,
    //which gave the result was not bad
    if(ip < 0.5)
        ag = ip * 29.53059 + 29.53059 / 2;
        ag = ip * 29.53059 - 29.53059 / 2;
    // Moon's age in days
    ag = Math.Floor(ag) + 1;
    return ag;

Draw moon:

private void DrawMoon()
    int Xpos, Ypos, Rpos;
    int Xpos1, Xpos2;
    double Phase;
    Phase = ip;
    // Width of 'ImageToDraw' Object = Width of 'PicMoon' control
    int PageWidth = PicMoon.Width;
    // Height of 'ImageToDraw' Object = Height of 'PicMoon' control
    int PageHeight = PicMoon.Height;
    // Initiate 'ImageToDraw' Object with size = size of control 'PicMoon' control
    Bitmap ImageToDraw = new Bitmap(PageWidth, PageHeight);
    // Create graphics object for alteration.
    Graphics newGraphics = Graphics.FromImage(ImageToDraw);
    Pen PenB = new Pen(Color.Black); // For darkness part of the moon
    Pen PenW = new Pen(Color.White); // For the lighted part of the moon
    for (Ypos=0; Ypos<= 45; Ypos++)
        Xpos = (int)(Math.Sqrt(45*45 - Ypos*Ypos));
        // Draw darkness part of the moon
        Point pB1 = new Point(90-Xpos, Ypos+90);
        Point pB2 = new Point(Xpos+90, Ypos+90);
        Point pB3 = new Point(90-Xpos, 90-Ypos);
        Point pB4 = new Point(Xpos+90, 90-Ypos);
        newGraphics.DrawLine(PenB, pB1, pB2);
        newGraphics.DrawLine(PenB, pB3, pB4);
        // Determine the edges of the lighted part of the moon
        Rpos = 2 * Xpos;
        if (Phase < 0.5)
            Xpos1 = - Xpos;
            Xpos2 = (int)(Rpos - 2*Phase*Rpos - Xpos);
            Xpos1 = Xpos;
            Xpos2 = (int)(Xpos - 2*Phase*Rpos + Rpos);
        // Draw the lighted part of the moon
        Point pW1 = new Point(Xpos1+90, 90-Ypos);
        Point pW2 = new Point(Xpos2+90, 90-Ypos);
        Point pW3 = new Point(Xpos1+90, Ypos+90);
        Point pW4 = new Point(Xpos2+90, Ypos+90);
        newGraphics.DrawLine(PenW, pW1, pW2);
        newGraphics.DrawLine(PenW, pW3, pW4);
    // Display the bitmap in the picture box.
    PicMoon.Image = ImageToDraw;
    // Release graphics object
    ImageToDraw = null;

You can go to source file to read the code, if you have any idea or find another code to calculate moon age, please tell me. 

Similar Articles