Moon’s Lunar Phase in JavaScript
Using Julian date, you can calculate the current phase of the moon by finding the lunar age as a percentage through the lunar month.
In lunar calendars, a lunar month is the time between two identical syzygies. This is the equivalent of 29.53059 Earth days.
Start by obtaining Julian date:
const getJulianDate = (date = new Date()) => {
const time = date.getTime();
const tzoffset = date.getTimezoneOffset()
return (time / 86400000) - (tzoffset / 1440) + 2440587.5;
}
With Julian date, calculate days or percentage through the lunar month:
const LUNAR_MONTH = 29.530588853;const getLunarAge = (date = new Date()) => {
const percent = getLunarAgePercent(date);
const age = percent * LUNAR_MONTH; return age;
}const getLunarAgePercent = (date = new Date()) => {
return normalize((getJulianDate(date) - 2451550.1) / LUNAR_MONTH);
}const normalize = value => {
value = value - Math.floor(value);
if (value < 0)
value = value + 1 return value;
}
Using the percentage through the lunar month, you can determine the current phase and precise position of shadow.
Lunar phases in order are as follows:
- 🌑 New
- 🌘 Waning Crescent
- 🌗 Last Quarter
- 🌖 Waning Gibbous
- 🌕 Full
- 🌔 Waxing Gibbous
- 🌓 First Quarter
- 🌒 Waxing Crescent
Apply these to percentage ranges to get the phase:
const getLunarPhase = (date = new Date()) => {
const age = getLunarAge(date); if (age < 1.84566)
return "New";
else if (age < 5.53699)
return "Waxing Crescent";
else if (age < 9.22831)
return "First Quarter";
else if (age < 12.91963)
return "Waxing Gibbous";
else if (age < 16.61096)
return "Full";
else if (age < 20.30228)
return "Waning Gibbous";
else if (age < 23.99361)
return "Last Quarter";
else if (age < 27.68493)
return "Waning Crescent"; return "New";
}
Or, use lunar age to determine whether the moon is waning or waxing:
const isWaxing = (date = new Date()) => {
const age = getLunarAge(date);
return age <= 14.765;
}const isWaning = (date = new Date()) => {
const age = getLunarAge(date);
return age > 14.765;
}
This code has been assembled into a library in my lunarphase-js GitHub project, or install via npm:
npm i lunarphase-js
Then, import and use as:
import * as Moon from 'lunarphase-js';// For a specific date, pass a date object to a function:
const date = new Date();
const phase = Moon.getLunarPhase(date);// Otherwise, current date will be used:
const phase = Moon.getLunarPhase();
API is as follows:
getLunarPhase()
— Get the current lunar phase from theLunarPhase
enum (ex: "Full")getLunarPhaseEmoji()
—Get the current lunar phase emoji from theLunarPhaseEmoji
enum (ex: "🌕")getLunarAge()
— Get the lunar age (ex: 16.54412413414952)getLunarAgePercent()
— Get the percentage through the lunar cycle (ex: 0.5602368519132597)isWaxing()
— Whether the moon is waxing (ex: false)isWaning()
— Whether the moon is waning (ex: true)getJulianDate()
— Get the current Julian date (ex: 2459244.5972259142)