When you don't need it, you don't need it. But when you do it can take a little thinking through.
The basic concept is fairly easy if you simply need rough, non-astronomical results. Take your target date/time, find out how far it is from a base date/time with a known phase (say New Moon), take the Lunar phase cycle period, and then the result is easy:
Phase = Delta Mod Period
Usually you'll want the value in more granular form. Maybe quarters is good enough, etc. so just divide the "Phase" value by the fraction of "Period" you want for granularity.
Another refinement is to make sure your base and target times are for the same time zone so you can avoid being off by 0 to 24 hours.
Here I used a UTC "base" New Moon date & time so I correct local time to UTC before calculating (this function is in the attached demo project). I found 24 images for the entire cycle so I am returning a phase value that is 1/24th of a Lunar period. I was careful to reduce the use of non-integer arithmetic and avoid rounding.
So hopefully this works out reasonably accurately for simple "display the phase of the Moon" purposes:
I've wrapped it in a small demo application for testing.
The basic concept is fairly easy if you simply need rough, non-astronomical results. Take your target date/time, find out how far it is from a base date/time with a known phase (say New Moon), take the Lunar phase cycle period, and then the result is easy:
Phase = Delta Mod Period
Usually you'll want the value in more granular form. Maybe quarters is good enough, etc. so just divide the "Phase" value by the fraction of "Period" you want for granularity.
Another refinement is to make sure your base and target times are for the same time zone so you can avoid being off by 0 to 24 hours.
Here I used a UTC "base" New Moon date & time so I correct local time to UTC before calculating (this function is in the attached demo project). I found 24 images for the entire cycle so I am returning a phase value that is 1/24th of a Lunar period. I was careful to reduce the use of non-integer arithmetic and avoid rounding.
So hopefully this works out reasonably accurately for simple "display the phase of the Moon" purposes:
Code:
Public Const PhaseBase As Date = #1/17/1980 9:18:00 PM# 'GMT/UTC.
Public Const LunarSynod As Long = 42524 'Minutes.
Public Function LunarPhase(ByVal TargetDate As Date) As Integer
'Returns lunar phase for TargetDate starting from PhaseBase
'timestamp forward, at 1/24 cycle intervals, i.e. values
'from 0 to 23:
'
' 0 = New Moon
' 6 = First Quarter
' 12 = Full Moon
' 18 = Last Quarter
LunarPhase = _
(Fix(DateDiff("n", PhaseBase, ToUTC(TargetDate))) Mod LunarSynod) _
\ (LunarSynod \ 24)
End Function