Recently I published a Fitbit app that calculates the Moon phase and then displays the proper phase image and illumination value. The user can select a different date or simply increment the date using buttons. Some feedback I received was that the app was fast and they wanted to understand why?
First, the app performs all calculations on the watch. No phone resources are need No GPS. No Internet. The calculations are based on a dateNow date object (this object is settable by the user though the interface that is not part of this discussion).
The calculation is based on an article I found by SubsySTEMs while performing an Internet search. Their paper broke the Moon phase calculation into a series of steps, which was easy to follow and translated directly to JavaScript. The output of their calculation is the number of days since the last New Moon. From there the Moon phase is determined. There are eight Moon phases (in order from New):
- New
- Waning Crescent
- Third Quarter
- Waning Gibbous
- Full
- Waxing Gibbous
- First Quarter
- Waxing Crescent
Using the days since the last New Moon you can find the phase but beware, each phase isn’t just 1/8 of 29.53 days. Shown below is the JavaScript that implements the attached paper.
function calMoonPhase() {
// calculate moon phase for date
let month = dateNow.getMonth() + 1;
let year = dateNow.getFullYear();
if(month < 3) {
year = year - 1;
month = month + 12;
}
let a = Math.floor(year/100);
let b = Math.floor(a/4);
let c = 2 - a + b;
let d = dateNow.getDate();
let e = Math.floor(365.25*(year+4716));
let f = Math.floor(30.6001 * (month + 1));
let jd = c + d + e + f - 1524.5;
let daysSinceNew = jd - 2451549.5;
let newMoons = daysSinceNew / 29.53;
<...Determine Moon phase...>
<...Determine image to show...>
<...Calculate illumination...>
}