« How can record companies increase their CD sales? | Main| Microsoft coughs up the cash »

Time for a programming challenge again

Category

I haven't had a programming challenge in a while for the Notes folks, so here's a new one.  

Create an @function formula that is passed a date field and returns True if there's a full moon on that date and false if there isn't.

Have fun.

Comments

Gravatar Image1 - Try this, based on: { Link }

I compared the results against several dates here { Link } and everything seemed to line up. I think you may end up a day off at times though, depending on what time zone you're in.

REM {Get a Date};
dateString := @Prompt([OkCancelEdit]; "Enter a Date"; "Please enter a date below:"; "mm/dd/yyyy");

REM {Convert the date to a Julian Day.};
m := @TextToNumber(@Word(dateString; "/"; 1));
d := @TextToNumber(@Word(dateString; "/"; 2));
y := @TextToNumber(@Word(dateString; "/"; 3));

y := @If(m <= 2; y - 1; y);
m := @If(m <= 2; m + 12; m);

c := 2 - @Integer(y / 100) + @Integer(y / 400);
jd := @Integer(1461 * (y + 4716) / 4) + @Integer(153 * (m + 1) / 5) + d + c - 1524.5;

REM {Determine which synodic month we're in, using an average length of 29.53 days per synodic month.};
k := (jd - 2451550.09765) / 29.530588853;

REM {The fractional value of k is how far along in the synodic month this day is. The full moon should come exactly halfway through the synodic month, so if the fractional value is 0.5 then today should be a full moon.};
moonPhase := "Nothing special";
fraction := @Round(k - @Integer(k); 0.01);
moonPhase := @If(fraction >= 0.99 | fraction <= 0.01; "New Moon"; moonPhase);
moonPhase := @If(fraction >= 0.24 & fraction <= 0.26; "First Quarter"; moonPhase);
moonPhase := @If(fraction >= 0.49 & fraction <= 0.51; "Full Moon"; moonPhase);
moonPhase := @If(fraction >= 0.74 & fraction <= 0.76; "Last Quarter"; moonPhase);


@Prompt([Ok]; "Moon Phase"; "date = " + dateString + @NewLine +
"jd = " + @Text(jd) + @NewLine +
"k = " + @Text(k) + @NewLine +
"fraction = " + @Text(fraction) + @NewLine +
"Moon Phase = " + moonPhase)

Gravatar Image2 - Hmm, Julian days prior to the year 2000 seem to be negative using that calculation for k. I think it'll work if you add:

fraction := @If(fraction < 0; fraction + 1; fraction);

just before the moon phase calculation though. At least for dates within the last hundred years or so.

And the "New Moon" calculation might be better stated as >= 0.98, after a few more tests...

Gravatar Image3 - You may also be able to simplify the Julian day calculation above using something like this:

SomeDate := @Date(2007; 11; 07);
jd := @Abs( ((SomeDate - @Date(1995; 10; 09)) / 86400) + 2450000 );

October 9, 1995 is a "known" Julian day of 2,450,000 , so it seems like you could just use the difference between your given date and that date for the calculation.

Gravatar Image4 - "Julian day" Heh heh.

OK, my contribution is done. Thank you Emoticon

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::rolleyes:;-)