-
-
Save endel/dfe6bb2fbe679781948c to your computer and use it in GitHub Desktop.
/* | |
* 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)); |
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');
@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');
@mrorigo, beautiful!
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());
Please fix that:
let c = e = jd = b = 0;
It creates 3 global variables: e
, jd
and b
What timezone is this script intended for?
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)
Here is a TypeScript version with a bit more polish: https://gist.github.com/datatypevoid/f4dd1f6439feaa588bb2aaf4f8f4361f
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. . .
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.
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
@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.
teamwork! 💪
Date 16 may 2022 actualy is the day start of fullmoon.
but this script shows that fullmoon start at 13 may 2022..
Is it something wrong?
Full moon was last night here, there are regional differences, but not by that much. You can check the exact time of the full moon for your area with an ephemeris such as this one: https://in-the-sky.org/ephemeris.php?ird=1&irs=1&ima=1&iph=1&iob=1&objtype=1&objpl=Moon&objtxt=the+Moon&tz=0&startday=1&startmonth=6&startyear=2022&interval=1&rows=100
And then cross-reference with the scripts results.
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?