Skip to content
{{ message }}

Instantly share code, notes, and snippets.

# endel/getMoonPhase.js

Created Mar 25, 2015
Get Moon Phase by Date, written in JavaScript
 /* * modified from http://www.voidware.com/moon_phase.htm */ function getMoonPhase(year, month, day) { var c = e = jd = b = 0; if (month < 3) { year--; month += 12; } ++month; c = 365.25 * year; e = 30.6 * month; jd = c + e + day - 694039.09; //jd is total days elapsed jd /= 29.5305882; //divide by the moon cycle b = parseInt(jd); //int(jd) -> b, take integer part of jd jd -= b; //subtract integer part to leave fractional part of original jd b = Math.round(jd * 8); //scale fraction from 0-8 and round if (b >= 8 ) { b = 0; //0 and 8 are the same so turn 8 into 0 } // 0 => New Moon // 1 => Waxing Crescent Moon // 2 => Quarter Moon // 3 => Waxing Gibbous Moon // 4 => Full Moon // 5 => Waning Gibbous Moon // 6 => Last Quarter Moon // 7 => Waning Crescent Moon return b; } console.log(getMoonPhase(2015, 3, 29));

### charlag commented Jan 7, 2018

 Hi! Thanks for the snipped. I find your code useful for my personal page but it is not licensed. Could you state the license please?

### imlinus commented Aug 14, 2018 • edited

 Thanks for sharing Endel! I modified your script slightly to return the name of the phase and put it inside an object. ``````// Original Snippet: https://gist.github.com/endel/dfe6bb2fbe679781948c var Moon = { phase: function (year, month, day) { var c = e = jd = b = 0; if (month < 3) { year--; month += 12; } ++month; c = 365.25 * year; e = 30.6 * month; jd = c + e + day - 694039.09; // jd is total days elapsed jd /= 29.5305882; // divide by the moon cycle b = parseInt(jd); // int(jd) -> b, take integer part of jd jd -= b; // subtract integer part to leave fractional part of original jd b = Math.round(jd * 8); // scale fraction from 0-8 and round if (b >= 8) b = 0; // 0 and 8 are the same so turn 8 into 0 switch (b) { case 0: return 'new-moon'; break; case 1: return 'waxing-crescent-moon'; break; case 2: return 'quarter-moon'; break; case 3: return 'waxing-gibbous-moon'; break; case 4: return 'full-moon'; break; case 5: return 'waning-gibbous-moon'; break; case 6: return 'last-quarter-moon'; break; case 7: return 'waning-crescent-moon'; break; } } }; // Moon.phase('2018', '01', '19'); ``````

### mrorigo commented Jan 16, 2019

 @imlinus I modified your script to not have a bloaty switch case, and actually return an object containing both the name and the number of the phase ;) ``````// Original Snippet: https://gist.github.com/endel/dfe6bb2fbe679781948c var Moon = { phases: ['new-moon', 'waxing-crescent-moon', 'quarter-moon', 'waxing-gibbous-moon', 'full-moon', 'waning-gibbous-moon', 'last-quarter-moon', 'waning-crescent-moon'], phase: function (year, month, day) { let c = e = jd = b = 0; if (month < 3) { year--; month += 12; } ++month; c = 365.25 * year; e = 30.6 * month; jd = c + e + day - 694039.09; // jd is total days elapsed jd /= 29.5305882; // divide by the moon cycle b = parseInt(jd); // int(jd) -> b, take integer part of jd jd -= b; // subtract integer part to leave fractional part of original jd b = Math.round(jd * 8); // scale fraction from 0-8 and round if (b >= 8) b = 0; // 0 and 8 are the same so turn 8 into 0 return {phase: b, name: Moon.phases[b]}; } }; // Moon.phase('2018', '01', '19'); ``````

### imlinus commented Feb 4, 2019

 @mrorigo, beautiful!

### t1mwillis commented Mar 15, 2019

 Thank you for this! Did just the trick for me :) In case anyone is wondering, the following returns an object with today's date that you can then inject into this. Month is 0 indexed. ``````var today = new Date(); var phase = Moon.phase(today.getFullYear(), today.getMonth()+1, today.getDate()); ``````

### corporateanon commented Mar 26, 2019

 Please fix that: ``````let c = e = jd = b = 0; `````` It creates 3 global variables: `e`, `jd` and `b`

### satouriko commented Nov 13, 2019

 What timezone is this script intended for?

### shawenyao commented Oct 16, 2020

 Thanks for the script. I borrowed function to build an app that shows what the Moon looks like on a given day. https://moon.shawenyao.com/?date=1980-07-31 (Note that if no date is passed, it defaults to today)

### datatypevoid commented Nov 1, 2020

 Here is a TypeScript version with a bit more polish: https://gist.github.com/datatypevoid/f4dd1f6439feaa588bb2aaf4f8f4361f

### orionrush commented Mar 10, 2021

 Is anyone else getting inconsistent results with this script? with the following `Moon.phase('2021', '03', '10')` I get a result of `waning-gibbous-moon`, however, the moon phase calendars I've consulted have the current phase as waning-crescent. This is a pretty big discrepancy. . .

### archipoeta commented Mar 11, 2021 • edited

 pretty sure the month is zero-indexed, as i am getting waning crescent with '02'. update: oh, no disregard-- Feb 10, 2021 was also waning crescent. update: i am able to repro the issue, something is weird here.

### archipoeta commented Mar 11, 2021

 Figured it out, the params need to be integers. Otherwise it breaks down on this line: `jd = c + e + day - 694039.09; // jd is total days elapsed` because it ends up being "int + int + str - int" and comes up n-days short depending on the day parameter. Now I get waning crescent for 3/10/2021

### orionrush commented Mar 11, 2021

 @archipoeta that's magic - thank you! So to make this solution more robust, it would be best to `parseInt` and make sure that day and month are two digits, and year four digits. It's perhaps less likely that year would get less than two digits. I guess a sensible fallback might be the current century if say it were provided only two digits.

### archipoeta commented Mar 11, 2021

 teamwork! 💪
to join this conversation on GitHub. Already have an account? Sign in to comment