Forum Moderators: open
I've been searching and searching (moon phase formula, lunar phase equation, etc., etc.) and while there's TONS of moon phase calculators out there, not one that I found offers the secret to how it's done - e.g. what the formula is to make such a calculation for varying days, months, years.
Thought I'd just scrape some site that already has the data but was then told that I've gotta create a function that will display ALL phases - not just the primary ones: New moon, first-quarter, full moon, last-quarter.
Now I just stumbled onto a site that indicates that moon phases are slightly different depending on location on earth... say what?
Anyway, there's my dilemma. Anybody got any idea where I could find such a formula?
Great appreciation for all responses!
Neophyte
By using this method, you deal only in 'seconds since the originally-established phase' and can do all the time/date conversions last.
Jim
I'm not sure how geolocation (longitude and latitude) affects the calculation, but if you test other calculators (that agree with one another) then you should be able to figure it out. HOWEVER, be certain that you are using the correct time, i.e. local or GMT/UTC (or possibly solar time).
Kaled.
Consider somebody in London and Sydney: they are half a day apart ... if you seek high accuracy that's going to be important to know if the moon is fully with it's shadow side to the earth or if there is that thinest of a line of sunlit moon showing through.
Consider moonrise and moonset times: it's going to be depended on where you are on the globe, just as it is with the sun.
When calculating moon or sun eclipses, the location of the observer is even more important (the are where the eclipse is visible is small and moves quite rapidly over the surface of the earth).
Thank you all so much for your insight and input. I've managed to build a preliminary function that spits out the the Moon Age based on Julian Days which sort of works - atleast I guess it does. I'm comparing my output to the output of some moon phase calculators on the net and most of the moon ages I'm getting are correct except one nagging Zero Moon Age output. Some calculators indicate that there is indeed a Zero Moon Age, others do not - hummm.
Anyway... the process continues.
Neophyte.
There's a book by Meeus called Astronomical Algorithms. You must get it. Not easy to find, but you can order it direct from the publisher.
In it, you'll find accurate methods for calculating all kinds of plantary, lunar and orbital events. Plus, you'll learn a lot about not-so-obvious challenges in astronomical computation from a pro.
As a beginning programmer back in the 90's, I used that book to build a virtual orrery & astro visualizer for my own amusement. Comparing my data with almanacs from the US Navy, they were all spot on to within fractions of seconds.
So, if you want accuracy, none of the formulas mentioned so far will cut it.
function moonphase(inyear,phase)
' input: approximate time and phase
' output: nearest requested phase moment in JD' inyear is the year (yyyy) plus decimal fraction for parts of the year.
' phase=0 - new
' phase=1 - first quarter
' phase=2 - full
' phase=3 - last quarterrealphase=phase * 0.25
' k is the lunation number. partial lunations correspond to partial phases. Algorithm is valid only for 1/4 parts of a lunation
' approximate value for k is (year - 2000) * 12.3685
' find the lunation (new moon) closest to date X
' this is often not accurate enough!k = INT((inyear - 2000) * 12.3685)
k = k + realphase
' where k = lunation integer,
' k+0 - new moon
' k+0.25 - first quarter
' k+0.5 - full moon
' k+0.75 - last quarter
' any other value for k will give meaningless results.T = k / 1236.85 ' time in Julian centuries since the epoch 2000
JDE = 2451550.09766 + (29.530588861 * k) + (0.00015437 * T*T) - (0.000000150 * T*T*T) + (0.00000000073 * T*T*T*T)M = 2.5534 + (29.10535670 * k) - (0.0000014 * T*T) - (0.00000011 * T*T*T) ' Suns mean anomaly
M_prime = 201.5643 + (385.81693528 * k) + (0.0107582 * T*T) + (0.00001238 * T*T*T) - (0.000000058 * T*T*T*T) ' Moons mean anomaly
F = 160.7108 + (390.67050284 * k) - (0.0016118 * T*T) - (0.00000227 * T*T*T) + (0.000000011 *T*T*T*T) ' moons argument of latitude
omega = 124.7746 - (1.56375588 * k) + (0.0020672 * T*T) + (0.00000215 * T*T*T)' planetary arguments
a_1 = 299.77 + (0.107408 * k) - (0.009173 * T*T*T)
a_2 = 251.88 + (0.016321 * k)
a_3 = 251.83 + (26.651886 * k)
a_4 = 349.42 + (36.412478 * k)
a_5 = 84.66 + (18.206239 * k)
a_6 = 141.74 + (53.303771 * k)
a_7 = 207.14 + (2.453732 * k)
a_8 = 154.84 + (7.306860 * k)
a_9 = 34.52 + (27.261239 * k)
a_10 = 207.19 + (0.121824 * k)
a_11 = 291.34 + (1.844379 * k)
a_12 = 161.72 + (24.198154 * k)
a_13 = 239.56 + (25.513099 * k)
a_14 = 331.55 + (3.592518 * k)E = 1 - (0.002516*T) - (0.0000074 * T*T)
if realphase = 0 then
' corrections for new moon
' these first 7 are a little different
corr = -0.40720 * dsin(M_prime)
corr = corr + 0.17241 * E * dsin(M)
corr = corr + 0.01608 * dsin(2*M_prime)
corr = corr + 0.01039 * dsin(2*F)
corr = corr + 0.00739 * E * dsin(M_prime - M)
corr = corr - 0.00514 * E * dsin(M_prime + M)
corr = corr + 0.00208 * E*E* dsin(2*M)
' the rest are the same for new and full
corr = corr - 0.00111 * dsin(M_prime - (2*F))
corr = corr - 0.00057 * dsin(M_prime + (2*F))
corr = corr + 0.00056 * E * dsin((2*M_prime) + M)
corr = corr - 0.00042 * dsin(3*M_prime)
corr = corr + 0.00042 * E * dsin(M + (2*F))
corr = corr + 0.00038 * E * dsin(M - (2*F))
corr = corr - 0.00024 * E * dsin((2*M_prime) - M)
corr = corr - 0.00017 * dsin(omega)
corr = corr - 0.00007 * dsin(M_prime + (2*M))
corr = corr + 0.00004 * dsin((2*M_prime)-(2*F))
corr = corr + 0.00004 * dsin(3*M)
corr = corr + 0.00003 * dsin(M_prime + M - (2*F))
corr = corr + 0.00003 * dsin((2*M_prime) + (2*F))
corr = corr - 0.00003 * dsin(M_prime + M + (2*F))
corr = corr + 0.00003 * dsin(M_prime - M + (2*F))
corr = corr - 0.00002 * dsin(M_prime - M - (2*F))
corr = corr - 0.00002 * dsin((3*M_prime) + M)
corr = corr + 0.00002 * dsin(4*M_prime)JDE = JDE + corr
elseif realphase = 0.5 then
' full moon
' these first 7 are a little different
corr = -0.40614 * dsin(M_prime)
corr = corr + 0.17302 * E * dsin(M)
corr = corr + 0.01614 * dsin(2*M_prime)
corr = corr + 0.01043 * dsin(2*F)
corr = corr + 0.00734 * E * dsin(M_prime - M)
corr = corr - 0.00515 * E * dsin(M_prime + M)
corr = corr + 0.00209 * E*E* dsin(2*M)
' the rest are the same for new and full
corr = corr - 0.00111 * dsin(M_prime - (2*F))
corr = corr - 0.00057 * dsin(M_prime + (2*F))
corr = corr + 0.00056 * E * dsin((2*M_prime) + M)
corr = corr - 0.00042 * dsin(3*M_prime)
corr = corr + 0.00042 * E * dsin(M + (2*F))
corr = corr + 0.00038 * E * dsin(M - (2*F))
corr = corr - 0.00024 * E * dsin((2*M_prime) - M)
corr = corr - 0.00017 * dsin(omega)
corr = corr - 0.00007 * dsin(M_prime + (2*M))
corr = corr + 0.00004 * dsin((2*M_prime)-(2*F))
corr = corr + 0.00004 * dsin(3*M)
corr = corr + 0.00003 * dsin(M_prime + M - (2*F))
corr = corr + 0.00003 * dsin((2*M_prime) + (2*F))
corr = corr - 0.00003 * dsin(M_prime + M + (2*F))
corr = corr + 0.00003 * dsin(M_prime - M + (2*F))
corr = corr - 0.00002 * dsin(M_prime - M - (2*F))
corr = corr - 0.00002 * dsin((3*M_prime) + M)
corr = corr + 0.00002 * dsin(4*M_prime)JDE = JDE + corr
elseif realphase=0.25 OR realphase=0.75 then
' first and last quarters
corr = -0.62801 * dsin(M_prime)
corr = corr + 0.17172 * E* dsin(M)
corr = corr - 0.01183 * E * dsin(M_prime + M)
corr = corr + 0.00862 * dsin(2*M_prime)
corr = corr + 0.00804 * dsin(2*F)
corr = corr + 0.00454 * E * dsin(M_prime - M)
corr = corr + 0.00204 * E*E* dsin(2*M)
corr = corr - 0.00108 * dsin(M_prime - (2*F))
corr = corr - 0.00070 * dsin(M_prime + (2*F))
corr = corr - 0.00040 * dsin(3*M_prime)
corr = corr - 0.00034 * E * dsin((2*M_prime) - M)
corr = corr + 0.00032 * E * dsin(M + (2*F))
corr = corr + 0.00032 * E * dsin(M - (2*F))
corr = corr + 0.00028 * E*E* dsin(M_prime + (2*M))
corr = corr + 0.00027 * E * dsin((2*M_prime) + M)
corr = corr - 0.00017 * dsin(omega)
corr = corr - 0.00005 * dsin(M_prime - M - (2*F))
corr = corr + 0.00004 * dsin((2*M_prime) + (2*F))
corr = corr - 0.00004 * dsin(M_prime + M + (2*F))
corr = corr + 0.00004 * dsin(M_prime - (2*M))
corr = corr + 0.00003 * dsin(M_prime + M - (2*F))
corr = corr + 0.00003 * dsin(3*M)
corr = corr + 0.00002 * dsin((2*M_prime) - (2*F))
corr = corr + 0.00002 * dsin(M_prime - M + (2*F))
corr = corr - 0.00002 * dsin((3*M_prime) + M)' calculate for quarter phases only
W = 0.00306 - (0.00038 * E * dcos(M)) + (0.00026 * dcos(M_prime)) - (0.00002 * dcos(M_prime - M)) + (0.00002 * dcos(M_prime + M)) + (0.00002 * dcos(2*F))if realphase = 0.25 then
corr = corr + W
elseif realphase = 0.75 then
corr = corr - W
end ifJDE = JDE + corr
end if
' additional corrections for all phases:
corr = 0.000325 * dsin(a_1)
corr = corr + 0.000165 * dsin (a_2)
corr = corr + 0.000164 * dsin (a_3)
corr = corr + 0.000126 * dsin (a_4)
corr = corr + 0.000110 * dsin (a_5)
corr = corr + 0.000062 * dsin (a_6)
corr = corr + 0.000060 * dsin (a_7)
corr = corr + 0.000056 * dsin (a_8)
corr = corr + 0.000047 * dsin (a_9)
corr = corr + 0.000042 * dsin (a_10)
corr = corr + 0.000040 * dsin (a_11)
corr = corr + 0.000037 * dsin (a_12)
corr = corr + 0.000035 * dsin (a_13)
corr = corr + 0.0000325 * dsin (a_14)JDE = JDE + corr
moonphase = JDE
end function
Wow, I'm speechless. Thanks so much. I've been scanning the VB Code and can pretty much understand most of what's going on. I'll give it a go in PHP and let you know the outcome.
I'm quite interested in the book you were mentioning as well - unfortunately I'm in the Philippines and I'm sure that a book like Astronomical Algorithms will be very difficult to find. I'll look it up on the I-Net and see if I can find the publisher and see if they'll send it overseas.
I would like to get my function to be as accurate as possible for various places on earth and I keep coming up with indications that I would need to somehow input lon/lat values as well.
Anyway, one step at a time. Thanks so very much for your informative posts.
Neophyte
I suppose if you want to get really technical there is a slight difference in how much of the illuminated surface you can see from one side of the earth or another, but this difference is really really really small.
The Earth has a diameter of 12,756 km and the moon has a mean orbital radius of 378,000 km this represents an arc of about 1.9 degrees - it's small but not really really really small.
Kaled.
Oh, another tip. be careful... The built-in PHP functions for converting Julian to Gregorian dates are not built right, and AFAIK they haven't been fixed. Julian dates begin at noon, and Gregorian Dates begin at midnight. you need to account for that when converting one to the other.
see my comment here from 2004
[php.net...]