mourner / suncalc

A tiny JavaScript library for calculating sun/moon positions and phases.
BSD 2-Clause "Simplified" License
3.07k stars 412 forks source link

please provide round of function for phase. #114

Open MrSpark2591 opened 6 years ago

MrSpark2591 commented 6 years ago

Thank you for great package. I needed some help on moonphase. from function suncalc.getMoonIllumination(date) i am getting values like 0.4945656646 how to map them to values you have provided in table. because 0.48756756 should be Waxing Gibbous where as 0.4945656646 should be Full Moon. Please provide some details to round of this phase.

marcelstoer commented 6 years ago

I was looking into the exact same thing. So, how to change https://github.com/mourner/suncalc/blob/master/suncalc.js#L238?

If you take the first algorithm at https://www.voidware.com/moon_phase.htm you could possibly apply the b = jd*8 + 0.5;b = b & 7; part to the line referenced above. So, in pseudo-code this could be:

intOnly((0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI) * 8 + 0.5) & 7

I have neither tested nor thought deeply about this, though.

tdulcet commented 5 years ago

Here is the correct code to calculate the moon phase for the current day:

function moonphase(phase1, phase2) {
    const percentages = [0, .25, .5, .75, 1];
    let index;

    if (phase1 <= phase2) {
        for (let i = 0; i < percentages.length; ++i) {
            if (percentages[i] >= phase1 && percentages[i] <= phase2) {
                index = 2 * i;
                break;
            } else if (percentages[i] > phase1) {
                index = (2 * i) - 1;
                break;
            }
        }
    } else {
        index = 0;
    }

    return index % 8;
}

function amoonphase(date1, date2) {
    const phase1 = SunCalc.getMoonIllumination(date1).phase;
    const phase2 = SunCalc.getMoonIllumination(date2).phase;
    return moonphase(phase1, phase2);
}

let now = new Date();
now.setHours(0, 0, 0, 0);
let anow = new Date(now);
anow.setDate(anow.getDate() + 1);

const index = amoonphase(now, anow);
console.log(now, index);

Similar code is being used on this webpage here to compare the moon phases returned from the SunCalc and MeeusJs libraries and Moontool (which I ported from C to JS). Note that you must click on the "More" near the bottom of the page to show MeeusJs.