Lunar Phase

Simple script for lunar/moon phases.
It’s not exact but pretty close for what I need.


--Classification of Lunar Phases
set {year:y, month:m, weekday:w, day:d, hours:h} to (current date)
if (m = 1) then
	set d to d - 1
else if (m = 2) then
	set d to d + 30
else
	set d to d + 28 + (m - 2) * 3059 / 100
end if
set g to (y - 1900) mod 19 + 1
set e to (11 * g + 18) mod 30
if (((e = 25) and (g > 11)) or (e = 24)) then
	set e to e + 1
end if
set fullness to ((((e + d) * 6 + 11) mod 177) / 22) as integer
if (fullness = 8) then set fullness to 0
set moonPhase to fullness

if moonPhase = 0 then
	set lunarCalendar to "New "
else if moonPhase = 1 then
	set lunarCalendar to "Waxing cresent "
else if moonPhase = 2 then
	set lunarCalendar to "First quarter "
else if moonPhase = 3 then
	set lunarCalendar to "Waxing gibbous "
else if moonPhase = 4 then
	set lunarCalendar to "Full "
else if moonPhase = 5 then
	set lunarCalendar to "Waning gibbous "
else if moonPhase = 6 then
	set lunarCalendar to "Third quarter "
else
	set lunarCalendar to "Waning cresent"
end if

return lunarCalendar & "moon"

Thank you, very nice!

Hi soxmonky.

Looks good. :slight_smile: But you need to test for m being either ‘January’ or ‘February’ in the first ‘if’ statement, because months aren’t automatically coerced to integer in equality tests. The '(m - 2) is OK though, because coercion is automatic in math operations.

set {year:y, month:m, weekday:w, day:d, hours:h} to (current date)
if (m = January) then
	set d to d - 1
else if (m = February) then
	set d to d + 30
else
	set d to d + 28 + (m - 2) * 3059 / 100
end if

. and getting rid of the if - else chain, weekday and hours parameters are not needed


set {year:y, month:m, day:d} to (current date)
if (m = January) then
	set d to d - 1
else if (m = February) then
	set d to d + 30
else
	set d to d + 28 + (m - 2) * 3059 / 100
end if
set g to (y - 1900) mod 19 + 1
set e to (11 * g + 18) mod 30
if (((e = 25) and (g > 11)) or (e = 24)) then
	set e to e + 1
end if
set moonPhase to (((((e + d) * 6 + 11) mod 177) / 22) as integer) mod 8
set descriptions to {"New", "Waxing cresent", "First quarter", "Waxing gibbous", "Full", "Waning gibbous", "Third quarter", "Waning cresent"}

return item (moonPhase + 1) of descriptions & space & "moon"

. and the first ‘if . else .’ statement would be statistically a little faster if inverted like so:

if (m > February) then
	set d to d + 28 + (m - 2) * 3059 / 100
else if (m = February) then
	set d to d + 30
else
	set d to d - 1
end if

In this version, ten of the twelve possible months are covered by the first test, so the second test (m = February) is only performed if ‘m’ is one of the other two months. In the original, the first test only caught January and so the second had to be done with all eleven of the other months. In this particular script, the difference is far too small to affect the user experience in any way, but it’s useful to think of such things when working out programme flows.

Hello soxmonkey.

Nice script! :slight_smile: You may find a couple of other scripts dealing with moon phases here: MacScripter / Accurate Table of Moonphases

Thanks McUsrll,
That’s an impressive script, but WAY more complex than I need. Plus it doesn’t involve installing Satimage.osax. Thanks for sharing McUsrll. Also thanks to StefanK & Nigel for cleaning up my original script!

Actually you should look into McUsr and Nigel’s advice. On the surface something may look good, but there could be bugs in your script on certain dates. Believe me. I’ve found several anomallies on some developer’s date scripts. The only hard part is trying to understand how they got it so accurate. Well basically you need to look into everything.

Good Luck,
kel

I didn’t give any advice, and I like his script. Its cool to be used from the calendar or the like, so you know what to expect with regards to the moon. It should do niceley in a notification. :slight_smile:

Hi McUsr,

I mixed up the sunrise script with the lunar. If you say soxmonkey’s script is accurate then I believe. :slight_smile: Almost. :smiley:

Have a good day!
kel

Does leap year have anything to do with the lunar phases?

Hello.

No, a leap year is a calendric invension, but a moon phase will occur one day earlier in a leap year, after feb the 29th, than it would have otherwise done.

Soxmonky’s script is quick, it is the kind of thing you’d use from the Calendar.app or something to not stall it. There is of course a tradeoff between speed and accuracy, but all that accuracy aren’t always needed, and when you are aware of it, that you may get a good hunch, but not total accuracy, then it is great. I think soxmonky stated that when he posted it.

Hi McUsr,

Nice explanation. So is there a good way to include the leap year in the calculations?

Edited: so you don’t have to rewrite the script every four years or less?

Edited: actually I think I know the answer, but who knows.

Edited: wasn’t there something about some year that didn’t have a leap year. I forgot about that, but I thnk there was something like that.

Aloha,
kel

Don’t mind me. just anal retentively thinking.

Edited: I remember now. You skip leap year on a certain year. Can’t remember when that was.

Nice to see so many Moone Boy’s out there. This script is just a small piece of a much bigger script I have run in the morning. Accuracy isn’t all that important but speed is. There’s about 3-4 days leeway for each moon phase, I’m pretty sure this script doesn’t take into account leap years, thats above my pay grade.

Hello.

The leap year may be somehow, baked into the formula for the moonphases for all we know. And the excempt for the leap years are century years that is not divisible by 400, like 1800, 1900 and so on.

As you probably know, the rationale behind leap years is that an astronomical year (the time it takes the earth to go round the sun) is approximately 365¼ (365.25) days. So if we normally have exactly 365 days in a calendar year, we have to add a day every fourth year to make up the accumulated four quarter-days’ difference.

But in fact, an astronomical year is closer to 365.2425 days ” three-quarters of a hundredth of a day less than 365¼. This means that every 100 leap years (or 400 years), we’ll have added 3 leap days too many. ((365 * 3 + 366) * 100 - 365.2425 * 400 = 3.) These three extra days are most conveniently and evenly omitted by only allowing one century year in every four to be a leap year. The century year which gets to remain a leap year is the one whose number is exactly divisible by 400. This is of course analogous to things at the lower-level: the last year of every four is a leap year, except that only the last century year of every four is a leap year.

Our proleptic Gregorian calendar only takes things to this level of accuracy, so while the number of days in a calendar year depends on the year itself and whereabouts in it you start counting, the length of 400 years is always exactly 365.2425 * 400, or 146097 days, wherever you start. This also happens to be an exact number of weeks, so the weekday-to-date cycle also repeats every 400 years! This has proved useful in the past when dealing with AppleScript date bugs or with dates outside the former official AppleScript date range (1 January 1000 00:00:00 to 31 December 9999 23:59:59). If something needed to be derived from a date which was outside the safe range, a date within the range could be used instead, provided it was a multiple of 400 years (12622780800 seconds) removed from the original. All the details would be exactly the same except for the year number. :slight_smile:

PS. The “safe range” is currently less than 400 years wide ((current date) + 1.26227808E+10 is an hour out for dates during daylight-saving time), so the method just described isn’t recommended!

Hello Nigel.

Even though the method has its deficiences nowadays, It’s still a great piece of background information. :slight_smile: