suncalc icon indicating copy to clipboard operation
suncalc copied to clipboard

Result for Moonrise/set when not alwaysUp or alwaysDown give undefined instead of false

Open hoekbrwr opened this issue 6 years ago • 1 comments

As stated in the header the output for these 2 results is undefined as you never set them. Add something like in .getMoonTimes result[alwaysUp] = false; result[alwaysDown] = false; To test it I have my lat en lon and local time are lat = 51.871513, lon = 4.665949; Date 2019-02-11;00:00:00 (slightly off for privacy) Now result for me is undefined for that position and time and also for a lot of others, causing Node-RED to fail.

hoekbrwr avatar Feb 12 '19 13:02 hoekbrwr

Greetings gentlemen,

I have a fix for function SunCalc.getMoonTimes, in next commented code.

//==================================================// SunCalc.getMoonTimes = function (date, lat, lng, inUTC) { var t = new Date(date); if (inUTC) t.setUTCHours(0, 0, 0, 0); else t.setHours(0, 0, 0, 0);

var hc = 0.133 * rad,
    h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,
    h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;

// go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
for (var i = 1; i <= 2*24; i += 2) { //===tge===20190731===extend in two 24-hours===
    h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;
    h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;

    a = (h0 + h2) / 2 - h1;
    b = (h2 - h0) / 2;
    xe = -b / (2 * a);
    ye = (a * xe + b) * xe + h1;
    d = b * b - 4 * a * h1;
    roots = 0;

    if (d >= 0) {
        dx = Math.sqrt(d) / (Math.abs(a) * 2);
        x1 = xe - dx;
        x2 = xe + dx;
        if (Math.abs(x1) <= 1) roots++;
        if (Math.abs(x2) <= 1) roots++; 
        if (x1 < -1) x1 = x2;
    }

    if (roots === 1) {
        if (h0 < 0) rise = i + x1;  // finds one : rise or set and store it
        else set = i + x1; 		  // until finds the second.
					  // a problem occurs when first find set.
					 // ( set < rise ????? )
									
    } else if (roots === 2) {
        rise = i + (ye < 0 ? x2 : x1);
        set = i + (ye < 0 ? x1 : x2);
    }
	if ( set && !rise ) set = null; //===tge===20190731===
						    // if find set, but not rise, then set canceled.
						    // so first find rise and then
						    // find set over night
	
    if (rise && set) {
		// console.log(i, rise, set, set - rise);
		if ( set < rise ){  //===tge===20190731===if found 
			set = null; // the impossible ( set < rise ), then set canceled. 
		}else{		// else
			break;	// brake the loop, we have solution
		}
	}

    h0 = h2;
}

var result = {};
if (rise) result.rise = hoursLater(t, rise);
if (set) result.set = hoursLater(t, set);

if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;

return result;

}; //==================================================//

Regards Evangelos

tsakal avatar Jul 31 '19 17:07 tsakal