mourner / suncalc

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

Sunrise / Sunset during "midnight sun" in polar areas #45

Open JasperG opened 9 years ago

JasperG commented 9 years ago

I've run into an issue;

For instance, at latitude 66.017 by longitude 29.136 (Northern Finland) at unix timestamp 1434447174, the sun rises on June 11th and does not set at all until July 3rd (Polar region, midnight sun).

I would like to get the time for the last sunrise, and get the time for the first following sundown, or vice versa, in winter time. However, I only seem to be able to get the first following sunrise and sunset for the day both those events are on the same day (June 10th and July 4th respectively). Otherwise, both sunset and sunrise return NaN, while I (apparently wrongly) expected the module to return a timestamp for only a sunrise, and only a sunset.

Would you be willing to assist me with this, or, fix this to make suncalc an even greater product?

mourner commented 9 years ago

Hmm, interesting. Thanks for the report! I'll think about this. The algorithm itself probably wasn't designed for cases like this, so at this point I'm not sure how to do this rather than just looping backwards and forwards with the date (which seems like a pretty acceptable workaround given that suncalc calculations are fast).

JasperG commented 9 years ago

Looping backward and forward (adding or subtracting a day to find the last sunrise / sunset) does not work; For instance:

At the given latitude, longitude and timestamp combination, the sun is currently up. While trying by going days backwards in time to find the last sunrise, the first result given is of the last day in which both a sunrise and sunset were present. The last timestamp retrievable is of a sunset, not a sunrise, even though the sun is currently up.

I thought, perhaps, calculating Jset and Jrise separately, instead of using Jnoon - (Jset - Jnoon). When entering this period of time, on June 11th for the given example coordinates, there is no Jset to be calculated. No luck so far.

Post scriptum; For wintertime, looping may be just fine. One day has a last sunrise and a last sunset (somewhere around noon), after which it stays dark for a certain period - followed by a sunrise at some later date. Summertime however, the event is started by a last runrise followed by no sunset on the same day.

warpling commented 9 years ago

I found these equations today for checking if a day will have a sunrise/sunset. I know this doesn't directly solve the problem at hand, but maybe this would be a useful check to prevent returning NaN?

Edit: realized that @JasperG's solution should be good enough.