Calculates lunar position, phases, distance and related quantities.
This module provides the analytical (Meeus Ch. 47) periodic-term
series for the Moon’s ecliptic longitude, latitude and distance,
as well as derived quantities such as illuminated fraction,
parallax and angular semi-diameter. These functions underpin the
higher-level lunar API in Astro and the topocentric
moonrise/moonset algorithm in Astro.Lunar.MoonRiseSet.
Lunar phases
The phase of the Moon is defined by the elongation — the geocentric angle between the Moon and the Sun. A new moon occurs at 0° elongation, first quarter at 90°, full moon at 180° and last quarter at 270°.
Because the Moon’s orbital plane is tilted ~5.1° relative to the ecliptic, a new moon can be up to ~5.2° from the Sun, which is why a solar eclipse does not occur every month.
Function groups
Position and geometry
lunar_position/1— ecliptic longitude, latitude and distancelunar_ecliptic_longitude/1,lunar_latitude/1,lunar_distance/1lunar_altitude/2,topocentric_lunar_altitude/2equatorial_horizontal_parallax/1,topocentric_lunar_parallax/2angular_semi_diameter/1,horizontal_dip/1
Phases and illumination
lunar_phase_at/1— phase angle (0–360°) at a momentilluminated_fraction_of_moon/1new_moon_phase/0,full_moon_phase/0,first_quarter_phase/0,last_quarter_phase/0
New moon and phase search
date_time_new_moon_before/1,date_time_new_moon_at_or_after/1,date_time_new_moon_nearest/1date_time_lunar_phase_at_or_before/2,date_time_lunar_phase_at_or_after/2nth_new_moon/1
Fundamental arguments (Julian centuries)
mean_lunar_ecliptic_longitude/1,lunar_elongation/1solar_anomaly/1,lunar_anomaly/1,lunar_node/1,moon_node/1
Time convention
Most functions in this module accept a moment (fractional
days since the epoch 0000-01-01). Use Astro.Time.date_time_to_moment/1
to convert dates or datetimes. Functions that accept Julian centuries
note this in their documentation.
Summary
Functions
Returns the Moon's angular semi-diameter in degrees for a given moment.
Returns the date time of a given lunar phase at or after a given date time or date.
Returns the date time of a given lunar phase at or before a given moment.
Returns the date time of the new moon at or after a given moment.
Returns the date time of the new moon before a given moment.
Returns the moment of the new moon nearest to a given moment.
Returns the Moon's equatorial horizontal parallax in degrees for a given moment.
Returns the first quarter phase angle in degrees.
Returns the full moon phase angle in degrees.
Returns the Moon's horizontal dip angle in degrees for a given moment.
Returns the fractional illumination of the Moon for a given moment as a float between 0.0 and 1.0.
Returns the last quarter phase angle in degrees.
Returns the Moon's geocentric altitude in degrees for a given moment and observer location.
Returns the Moon's mean anomaly in degrees for a given number of Julian centuries from J2000.0.
Returns the Moon's distance from the Earth in meters for a given moment.
Returns the mean lunar elongation in degrees for a given number of Julian centuries from J2000.0.
Returns the Moon's ecliptic latitude in degrees for a given moment.
Returns the Moon's ascending node longitude in degrees for a given moment.
Returns the lunar phase as a float number of degrees at a given moment.
Returns the Moon's equatorial position (right ascension, declination, distance) for a given moment.
Returns the lunar radius in kilometers.
Returns the mean lunar ecliptic longitude in degrees for a given number of Julian centuries from J2000.0.
Returns the mean longitude of the Moon's ascending node in degrees for a given number of Julian centuries from J2000.0.
Returns the new moon phase angle in degrees.
Returns the Sun's mean anomaly in degrees for a given number of Julian centuries from J2000.0.
Returns the topocentric lunar parallax in degrees for a given moment and observer location.
Functions
@spec angular_semi_diameter(t :: Astro.Time.moment()) :: Astro.angle()
Returns the Moon's angular semi-diameter in degrees for a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- The angular semi-diameter as a float in degrees.
@spec date_time_lunar_phase_at_or_after( t :: Astro.Time.moment(), phase :: Astro.phase() ) :: Astro.Time.moment()
Returns the date time of a given lunar phase at or after a given date time or date.
Arguments
t, aAstro.Time.moment/0float number of days since0000-01-01.phaseis the required lunar phase expressed as a float number of degrees between0and360
Returns
- a
Astro.Time.moment/0which is a float number of days since0000-01-01.
Example
iex> Astro.Lunar.date_time_lunar_phase_at_or_after(738368, Astro.Lunar.full_moon_phase())
738389.5014214877
@spec date_time_lunar_phase_at_or_before( t :: Astro.Time.moment(), phase :: Astro.phase() ) :: Astro.Time.moment()
Returns the date time of a given lunar phase at or before a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.phaseis the required lunar phase expressed as a float number of degrees between0.0and360.0
Returns
- A
Astro.Time.moment/0float number of days since0000-01-01.
Example
iex> Astro.Lunar.date_time_lunar_phase_at_or_before(738368, Astro.Lunar.new_moon_phase())
738346.053171558
@spec date_time_new_moon_at_or_after(t :: Astro.Time.moment()) :: Astro.Time.moment()
Returns the date time of the new moon at or after a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- a
Astro.Time.moment/0which is a float number of days since0000-01-01
Example
iex> Astro.Lunar.date_time_new_moon_at_or_after(738390)
738405.0359290199
@spec date_time_new_moon_before(t :: Astro.Time.moment()) :: Astro.Time.moment()
Returns the date time of the new moon before a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- A
Astro.Time.moment/0float number of days since0000-01-01.
Example
iex> Astro.Lunar.date_time_new_moon_before 738390
738375.5764772523
@spec date_time_new_moon_nearest(t :: Astro.Time.moment()) :: Astro.Time.moment()
Returns the moment of the new moon nearest to a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- a
Astro.Time.moment/0which is a float number of days since0000-01-01
Example
iex> Astro.Lunar.date_time_new_moon_nearest(738390)
738375.5764755815
@spec equatorial_horizontal_parallax(t :: Astro.Time.moment()) :: Astro.angle()
Returns the Moon's equatorial horizontal parallax in degrees for a given moment.
The horizontal parallax is the angle subtended by Earth's equatorial radius as seen from the Moon, or equivalently the maximum apparent displacement of the Moon caused by the observer being on Earth's surface rather than its centre.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- The equatorial horizontal parallax as a float in degrees.
Examples
iex> Astro.Lunar.equatorial_horizontal_parallax(738390)
...> |> Float.round(4)
0.0167
@spec first_quarter_phase() :: Astro.phase()
Returns the first quarter phase angle in degrees.
Returns
90.0
Examples
iex> Astro.Lunar.first_quarter_phase()
90.0
@spec full_moon_phase() :: Astro.phase()
Returns the full moon phase angle in degrees.
Returns
180.0
Examples
iex> Astro.Lunar.full_moon_phase()
180.0
@spec horizontal_dip(t :: Astro.Time.moment()) :: Astro.angle()
Returns the Moon's horizontal dip angle in degrees for a given moment.
The horizontal dip combines atmospheric refraction, the Moon's angular semi-diameter and the equatorial horizontal parallax to define the threshold altitude for moonrise/moonset.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- The horizontal dip as a float in degrees (negative value).
@spec illuminated_fraction_of_moon(Astro.Time.time()) :: float()
Returns the fractional illumination of the Moon for a given moment as a float between 0.0 and 1.0.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- The fractional illumination of the Moon as a float
between
0.0(new moon) and1.0(full moon).
Examples
iex> Astro.Lunar.illuminated_fraction_of_moon(738390)
...> |> Float.round(4)
0.9951
@spec last_quarter_phase() :: Astro.phase()
Returns the last quarter phase angle in degrees.
Returns
270.0
Examples
iex> Astro.Lunar.last_quarter_phase()
270.0
@spec lunar_altitude(Astro.Time.moment(), Geo.PointZ.t()) :: Astro.angle()
Returns the Moon's geocentric altitude in degrees for a given moment and observer location.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.locationis aGeo.PointZstruct with{longitude, latitude, altitude}coordinates.
Returns
- The geocentric altitude in degrees, ranging from -180.0 to 180.0.
@spec lunar_anomaly(c :: Astro.Time.julian_centuries()) :: Astro.angle()
Returns the Moon's mean anomaly in degrees for a given number of Julian centuries from J2000.0.
Arguments
cis the number of Julian centuries from J2000.0.
Returns
- The mean lunar anomaly as a float in degrees.
@spec lunar_distance(t :: Astro.Time.moment()) :: Astro.meters()
Returns the Moon's distance from the Earth in meters for a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- The Earth-Moon distance as a float in meters.
Examples
iex> Astro.Lunar.lunar_distance(738390) |> trunc()
381251299
@spec lunar_elongation(c :: Astro.Time.julian_centuries()) :: Astro.angle()
Returns the mean lunar elongation in degrees for a given number of Julian centuries from J2000.0.
Arguments
cis the number of Julian centuries from J2000.0.
Returns
- The mean elongation as a float in degrees.
@spec lunar_latitude(Astro.Time.moment()) :: Astro.angle()
Returns the Moon's ecliptic latitude in degrees for a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- The ecliptic latitude as a float in degrees.
Examples
iex> Astro.Lunar.lunar_latitude(738390) |> Float.round(4)
-5.0099
@spec lunar_node(t :: Astro.Time.moment()) :: Astro.angle()
Returns the Moon's ascending node longitude in degrees for a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- The ascending node longitude as a float in degrees, ranging from -90.0 to 90.0.
@spec lunar_phase_at(t :: Astro.Time.moment()) :: Astro.angle()
Returns the lunar phase as a float number of degrees at a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- the lunar phase as a float number of degrees.
Example
iex> Astro.Lunar.lunar_phase_at(738389.5007195644)
179.9911519346108
iex> Astro.Lunar.lunar_phase_at(738346.0544609067)
0.013592004555277981
@spec lunar_position(Astro.Time.moment()) :: {Astro.angle(), Astro.angle(), Astro.meters()}
Returns the Moon's equatorial position (right ascension, declination, distance) for a given moment.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.
Returns
- A 3-tuple
{right_ascension, declination, distance}where right ascension and declination are in degrees and distance is in meters.
Examples
iex> {ra, _dec, _dist} = Astro.Lunar.lunar_position(738390)
iex> Float.round(ra, 2)
-19.96
@spec lunar_radius() :: Astro.kilometers()
Returns the lunar radius in kilometers.
The IAU 2015 value of 1737.4 km is used.
Arguments
None.
Returns
- The lunar radius as a float in kilometers.
Examples
iex> Astro.Lunar.lunar_radius()
1737.4
@spec mean_lunar_ecliptic_longitude(c :: Astro.Time.julian_centuries()) :: Astro.angle()
Returns the mean lunar ecliptic longitude in degrees for a given number of Julian centuries from J2000.0.
Arguments
cis the number of Julian centuries from J2000.0.
Returns
- The mean ecliptic longitude as a float in degrees.
@spec moon_node(c :: Astro.Time.julian_centuries()) :: Astro.angle()
Returns the mean longitude of the Moon's ascending node in degrees for a given number of Julian centuries from J2000.0.
Arguments
cis the number of Julian centuries from J2000.0.
Returns
- The mean longitude of the ascending node as a float in degrees.
@spec new_moon_phase() :: Astro.phase()
Returns the new moon phase angle in degrees.
Returns
0.0
Examples
iex> Astro.Lunar.new_moon_phase()
0.0
@spec solar_anomaly(c :: Astro.Time.julian_centuries()) :: Astro.angle()
Returns the Sun's mean anomaly in degrees for a given number of Julian centuries from J2000.0.
Arguments
cis the number of Julian centuries from J2000.0.
Returns
- The mean solar anomaly as a float in degrees.
@spec topocentric_lunar_parallax(t :: Astro.Time.moment(), location :: Geo.PointZ.t()) :: Astro.angle()
Returns the topocentric lunar parallax in degrees for a given moment and observer location.
This is the observer-specific parallax (also called the parallax in
altitude), which varies with the observer's latitude and the Moon's
altitude above their horizon — as opposed to the equatorial horizontal
parallax returned by equatorial_horizontal_parallax/1, which is
location-independent.
Arguments
tis aAstro.Time.moment/0float number of days since0000-01-01.locationis aGeo.PointZstruct with{longitude, latitude, altitude}coordinates.
Returns
- The topocentric parallax as a float in degrees.