/* Program Name: Moon Phases
Author: Ben Jacobs
Compilation: gcc -o moon moon.c -lm (NOTE: must be linked to the math
library, I don't know how you manage this in a non-UNIX environment)
Description: Gets user input for date & time and gives the current phase
of the moon. The "fullness" of the moon is stored in the double precision
float "F".
Comments: I don't take an credit for the moon phase math. I found it in a
program written in QBASIC by J. Stein Carter who found the math in
"Practical Astronomy with Your Calculator", 3rd Ed by Duffett-Smith, Peter.
1988 Cambridge Univ. Press. All I did was translate it into C.
I realize it uses a pretty excessive amount of double precision floats but
that's how I found the calculations and I didn't want to mess with them
that much.
Bug report: dooberwah@crosswinds.net
*/
#include
#include
#define PI 3.141592654
int day_of_year(int year, int month, int day);
int fullness(int d, int *numdays, double *F, double *x);
int main(void)
{
int month, day, year, leap;
int hour, minute, second;
int datenum, numdays;
double F, x;
/* Gets date from user. Returns -1 if user enters bad date */
printf("Input date mm/dd/yyyy > ");
scanf("%d/%d/%d", &month, &day, &year);
if ((month < 1 || month > 12) || (day < 1 || day > 365) || year <= 0) {
printf("Invalid date.\n");
return -1;
}
/* Checks to see if year is a leap year */
leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
printf("Input time in 24 hour formatt hh:mm:ss > ");
scanf("%d:%d:%d", &hour, &minute, &second);
if ((hour < 1 || hour > 24) || (minute < 1 || minute > 60) || (second < 1 || second > 60)) {
printf("Invalid time.\n");
return -1;
}
datenum = day_of_year(year, month, day);
fullness(datenum, &numdays, &F, &x);
if (F < 0.003)
printf("The moon is currently a new moon.\n");
else if (F < 0.47)
printf("The moon is in a first quarter moon.\n");
else if (F > 0.47 && F < 0.53)
printf("The moon is currently a half moon.\n");
else if (F > 0.997)
printf("The moon is currently a full moon.\n");
else if (F > 0.53)
printf("The moon is currently in the third quarter.\n");
return 0;
}
/* Here's a structure with the number of days in each month. for leap and
non-leap years. It's like the monthname array in the way that it uses
a 0 in the first place (or "Illegal month" in monthname) so that January
is the first month instead of the 0th. */
static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
/* this function figures the day number out of 365 for any given day in any
month. */
int day_of_year(int year, int month, int day)
{
int i, leap;
leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
for (i = 1; i < month; i++)
day += daytab[leap][i];
return day;
}
int fullness(int d, int *numdays, double *F, double *x)
{
double nCounter, N, Mo, Ec, lamda, l, Mm, N65, Ev, Ae, A3, Mmp, A4, lp, V, lpp, D67;
*numdays = d + nCounter / 2;
N = *numdays * (360 / 365.242191);
N = abs(N) - abs(N / 360) * 360;
Mo = N + 279.403303 - 282.768422;
if (Mo < 0)
Mo = Mo + 360;
Ec = 360 * .016713 * sin(Mo * PI / 180) / PI;
lamda = N + Ec + 279.403303;
if (lamda > 360)
lamda = lamda - 360;
l = 13.1763966 * *numdays + 318.351648;
l = abs(l) - abs(l / 360) * 360;
Mm = l - .1114041 * d - 36.34041;
Mm = abs(Mm) - abs(Mm / 360) * 360;
N65 = 318.510107 - .0529539 * *numdays;
N65 = abs(N65) - abs(N65 / 360) * 360;
Ev = 1.2739 * sin((2 * (1 - lamda) - Mm) * PI / 180);
Ae = .1858 * sin(Mo * PI / 180);
A3 = .37 * sin(Mo * PI / 180);
Mmp = Mm + Ev - Ae - A3;
Ec = 6.2886 * sin(Mmp * PI / 180);
A4 = .214 * sin((2 * Mmp) * PI / 180);
lp = l + Ev + Ec - Ae + A4;
V = .6583 * sin((2 * (lp - lamda)) * PI / 180);
lpp = lp + V;
D67 = lpp - lamda;
*F = .5 * (1 - cos(D67 * PI / 180));
*x = (sin(D67 * PI / 180));
return 0;
}