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

Wrong calculation of night and nightEnd for polar night and very high altitudes. #70

Open filchos opened 8 years ago

filchos commented 8 years ago

When latitude is 89.5 °C (almost the north pole), strange things happen with calling getTimes() for different dates.

console.log(SunCalc.getTimes(new Date(2016, 1, 1, 12, 0, 0), 89.5, 21));

will result in Invalid Date on night and nightEnd, which is correct because of the polar night.

console.log(SunCalc.getTimes(new Date(2016, 0, 31, 12, 0, 0), 89.5, 21));

will result in night: Sun Jan 31 2016 22:07:25 GMT+0100 (CET) and nightEnd: Sun Jan 31 2016 01:33:42 GMT+0100 (CET) which seems wrong. It should say Invalid Date, too on these properties.

JasperG commented 8 years ago

Related to #45.

See "Computing rise/set times" by Paul Schlyter , chapter 2.

Currently unmerged patch to #45 may be used to solve this issue.

beingmrkenny commented 8 years ago

I'm also seeing invalid dates being returned for night and nightEnd in Sheffield, UK. However I don't think this is necessarily a bug. The northern parts of the UK do get a sunrise and sunset every day, but for a week or two in the summer months we never actually reach true astronomical night.

I would suggest returning something other than an invalid date in this case, such as false or null, but otherwise it's correct behaviour not to have a night and a nightEnd — at least for the north of the UK.

Test lat/lng for Sheffield: 53.379979, -1.469407 — on July 28, 2016.

Wikipedia has this:

At latitudes greater than about 48.5 degrees North or South, on dates near the summer solstice, twilight can last from sunset to sunrise, since the Sun does not go more than 18 degrees below the horizon, so complete darkness does not occur even at midnight. These latitudes include many densely populated regions of the Earth, including the entire United Kingdom and other countries in northern Europe.

tbyte80 commented 7 years ago

I also ran into this issue. Instead of "Invalid Date" I guess it would be preferable to return boolean true in cases where there is no sunrise/sunset because the sun is always up or boolean false if there is no sunrise/sunset because the sun is always down . It's currently not possible to distinguish between the two cases.

Same for the twilight phases.

mnpenner commented 7 years ago

I'm also experiencing this issue for Surrey, BC

SunCalc.getTimes(new Date(2017,5,21,12,0,0),49.1,-122.8)

I thought this was wrong, but I guess not according to this page:

I never knew we didn't have a night!

JonSilver commented 7 years ago

London today, near midsummer - nightEnd and night both invalid dates

let lat = 51.5
let lon = -0.1

let times = SunCalc.getTimes(new Date(), lat, lon)
let position = SunCalc.getPosition(new Date(), lat, lon)

console.log(times)
{ solarNoon: 2017-06-20T12:03:15.661Z,
  nadir: 2017-06-20T00:03:15.661Z,
  sunrise: 2017-06-20T03:44:08.434Z,
  sunset: 2017-06-20T20:22:22.887Z,
  sunriseEnd: 2017-06-20T03:48:39.266Z,
  sunsetStart: 2017-06-20T20:17:52.055Z,
  dawn: 2017-06-20T02:56:23.383Z,
  dusk: 2017-06-20T21:10:07.938Z,
  nauticalDawn: 2017-06-20T01:41:47.712Z,
  nauticalDusk: 2017-06-20T22:24:43.610Z,
  nightEnd: Invalid Date,
  night: Invalid Date,
  goldenHourEnd: 2017-06-20T04:38:22.661Z,
  goldenHour: 2017-06-20T19:28:08.660Z }

console.log(position)
{ azimuth: 1.3489914287235802, altitude: 0.6975538136465885 }
tbyte80 commented 7 years ago

This is actually correct as the sun doesn't go below astronomical twilight this time of the year => thus no night phase.