Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

imlinus commented Aug 14, 2018

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

imlinus commented Feb 4, 2019

@mrorigo, beautiful!

@t1mwillis

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

corporateanon commented Mar 26, 2019

Please fix that:

let c = e = jd = b = 0;

It creates 3 global variables: e, jd and b

@rikakomoe

This comment has been minimized.

Copy link

rikakomoe commented Nov 13, 2019

What timezone is this script intended for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.