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

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

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

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

commented Feb 4, 2019

@mrorigo, beautiful!

@t1mwillis

This comment has been minimized.

Copy link

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

commented Mar 26, 2019

Please fix that:

let c = e = jd = b = 0;

It creates 3 global variables: e, jd and b

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.