[astro] Astronomy calculations (sunrise, sunset, moonrise, moonset, moon phase equinox, solstice, ...)

Please say hi to a new lib, Astro that aims to deliver easy-to-consume astronomy calculations of practical use. For now it only calculates sunrise and sunset. In testing its precision is within 1 minute of the results returns from DateAndTime.com.

It makes use of tz_world to dereference geo coordinates to a timezone and tzdata for time zone conversions.

This lib started our as a requirement to support certain solar, lunar and lunisolar calendars but it has wider applicability.


# Sunrise in Sydney on December 4th
iex> Astro.sunrise({151.20666584, -33.8559799094}, ~D[2019-12-04])
{:ok, #DateTime<2019-12-04 05:37:00.000000+11:00 AEDT Australia/Sydney>}

# Sunset in Sydney on December 4th
iex> Astro.sunset({151.20666584, -33.8559799094}, ~D[2019-12-04])
{:ok, #DateTime<2019-12-04 19:53:00.000000+11:00 AEDT Australia/Sydney>}

# Sunset in the town of Alert in Nunavut, Canada
# ...doesn't exist since there is no sunset in summer
iex> Astro.sunset({-62.3481, 82.5018}, ~D[2019-07-01])
{:error, :no_time}

# ...or sunrise in winter
iex> Astro.sunrise({-62.3481, 82.5018}, ~D[2019-12-04])
{:error, :no_time}

Next steps

  • [X] Sunrise
  • [X] Sunset
  • [ ] Solstice
  • [ ] Equinox
  • [ ] Moon phase
  • [ ] Moon rise
  • [ ] Moon set

New version 0.2.0 is now out:


  • Add Astro.equinox/2and Astro.solstice/2 to calculate solstices and equinoxes for a year. From these can be derived the seasons.

  • Add Astro.Time.datetime_from_julian_days/1

  • Add Astro.Time.utc_datetime_from_terrestrial_datetime/1

Now on to lunar calculations (phase, moonrise, moonset)… And to implement the Persian calendar (which is a Solar based calendar).


New version 0.3.0 is now out:

Change in behaviour

  • Seconds are no longer truncated to zero when calculating datetimes and durations


  • Add Astro.solar_noon/2 to return the true solar noon for a location and date

  • Add Astro.hours_of_daylight/2 to return hours, minutes and seconds as a Time.t() representing the number of daylight hours for a give location and date

  • Add Astro.sun_apparent_longitude/1 to return the apparent solar longitude on a given date. The result, a number of degrees between 0 and 360, can be used to determine the seasons.

This completes the work required to support the Persian calendar which will be landing on hex.pm in the next couple of days.

1 Like