# `Astro.Lunar`
[🔗](https://github.com/kipcole9/astro/blob/v2.11.0/lib/astro/lunar.ex#L1)

Calculates lunar position, phases, distance and related quantities.

This module provides the Moon's position and derived quantities such as
the phase, the 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`.

## Two sources of the Moon's position

The Moon's apparent position comes from one of two sources:

* **The JPL DE440s ephemeris**, read by `Astro.Ephemeris`. It is a
  numerical integration fitted to lunar laser ranging, accurate to well
  under a milliarcsecond, but it covers a limited span of years
  (1900–2100 for the file bundled with Astro).

* **Analytical series**, computed in this module: the periodic series
  of Meeus, *Astronomical Algorithms*, chapter 47, abridged from the
  ELP-2000/82 lunar theory. They are less accurate (about 3″ RMS in
  longitude near the present) but give a position for any date.

The [accuracy guide](accuracy.md) compares the two.

The series are sums of sine and cosine terms whose arguments combine
five fundamental arguments: `mean_lunar_ecliptic_longitude/1`,
`lunar_elongation/1`, `solar_anomaly/1`, `lunar_anomaly/1` and
`moon_node/1`.

## 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` — right ascension, declination and distance
* `lunar_ecliptic_longitude/1`, `lunar_latitude/1`, `lunar_distance/1`
* `lunar_altitude/2`, `topocentric_lunar_altitude/2`
* `equatorial_horizontal_parallax/1`, `topocentric_lunar_parallax/2`
* `angular_semi_diameter/1`, `horizontal_dip/1`

### Phases and illumination

* `lunar_phase_at/1` — phase angle (0–360°) at a moment
* `illuminated_fraction_of_moon/1`
* `new_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/1`
* `date_time_lunar_phase_at_or_before/2`, `date_time_lunar_phase_at_or_after/2`
* `nth_new_moon/1`

### Analytical series

* `analytical_lunar_ecliptic_position/1` — apparent ecliptic longitude, latitude and distance
* `analytical_lunar_position/1` — apparent right ascension, declination and distance

### Fundamental arguments (Julian centuries)

* `mean_lunar_ecliptic_longitude/1`, `lunar_elongation/1`
* `solar_anomaly/1`, `lunar_anomaly/1`, `moon_node/1`, `lunar_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.

# `analytical_lunar_ecliptic_position`
*since 2.10.0* 

```elixir
@spec analytical_lunar_ecliptic_position(Astro.Time.moment()) ::
  {float(), float(), float()}
```

Returns the Moon's apparent geocentric ecliptic position from analytical
series.

The longitude, latitude and distance are the periodic series of Meeus,
*Astronomical Algorithms*, chapter 47, with the nutation in longitude of
`Astro.Earth.nutation/1` added to give the apparent longitude. Each
periodic term's argument combines the fundamental arguments; terms that
depend on the Sun's anomaly are scaled by the eccentricity factor of the
Earth's orbit. Over 1900–2100 the longitude agrees with the JPL DE440s
ephemeris to about 3″ RMS.

### Arguments

* `t` is a moment (fractional days since the epoch).

### Returns

* `{longitude, latitude, distance}` where `longitude` is in degrees in
  the range 0 to 360, `latitude` is in degrees and `distance` is in
  metres.

### Accuracy

Against JPL over 1900–2100: longitude 2.7″ RMS and 13.5″ at most,
latitude 1.1″ RMS and 4.9″ at most, and distance 2.9 km RMS. The
[accuracy guide](accuracy.md) gives the details, and how the series
drift far from the present.

### Examples

Meeus, *Astronomical Algorithms*, example 47.a, gives 133.167265°,
−3.229126° and 368,409.7 km for 1992 April 12 at 0h TD; the small
difference is Meeus's value of the nutation:

    iex> moment = Astro.Time.dynamical_time_to_moment((2_448_724.5 - 2_451_545.0) * 86_400.0)
    iex> {longitude, latitude, distance} = Astro.Lunar.analytical_lunar_ecliptic_position(moment)
    iex> {Float.round(longitude, 6), Float.round(latitude, 6), Float.round(distance / 1000.0, 1)}
    {133.167263, -3.229131, 368409.7}

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Ephemeride Lunaire Parisienne](https://en.wikipedia.org/wiki/Ephemeride_Lunaire_Parisienne), Wikipedia.

# `analytical_lunar_position`
*since 2.10.0* 

```elixir
@spec analytical_lunar_position(Astro.Time.moment()) :: {float(), float(), float()}
```

Returns the Moon's apparent geocentric right ascension, declination and
distance from analytical series.

The ecliptic position of `analytical_lunar_ecliptic_position/1` is
rotated to the equator with the true obliquity of the ecliptic by
`Astro.Coordinates.ecliptic_to_equatorial/3`.

### Arguments

* `t` is a moment (fractional days since the epoch).

### Returns

* `{right_ascension, declination, distance}` where `right_ascension`
  is in degrees in the range 0 to 360, `declination` is in degrees and
  `distance` is in metres.

### Accuracy

Against JPL over 1900–2100: right ascension 2.7″ RMS and
declination 1.3″ RMS (10.1″ and 6.5″ at most). The
[accuracy guide](accuracy.md) gives the details.

### Examples

Meeus, *Astronomical Algorithms*, example 47.a, gives 134.688470° and
13.768368° for 1992 April 12 at 0h TD:

    iex> moment = Astro.Time.dynamical_time_to_moment((2_448_724.5 - 2_451_545.0) * 86_400.0)
    iex> {right_ascension, declination, _distance} = Astro.Lunar.analytical_lunar_position(moment)
    iex> {Float.round(right_ascension, 6), Float.round(declination, 6)}
    {134.688466, 13.768364}

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 13 (transformation of coordinates).

# `angular_semi_diameter`

```elixir
@spec angular_semi_diameter(t :: Astro.Time.moment()) :: Astro.angle()
```

Returns the Moon's angular semi-diameter in degrees for a given moment.

### Arguments

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* The angular semi-diameter as a float in degrees.

### Accuracy

It follows from the Moon's distance, which the series give within
2.9 km RMS of JPL; that changes it by under 0.03″.

### Examples

    iex> Astro.Lunar.angular_semi_diameter(Astro.Time.j2000()) |> Float.round(4)
    0.2473

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 55 (semidiameters of the Sun, Moon and planets).

* [Angular diameter](https://en.wikipedia.org/wiki/Angular_diameter), Wikipedia.

# `date_time_lunar_phase_at_or_after`
*since 0.5.0* 

```elixir
@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`, a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

* `phase` is the required lunar phase expressed
  as a float number of degrees between `0` and
  `360`.

### Returns

* a `t:Astro.Time.moment/0` which is a float number of days
  since `0000-01-01`.

### Accuracy

The search ends within a millisecond of the crossing. Outside the
ephemeris the series place the phases within about 6 s RMS of JPL
over 1900–2100. See `Astro.date_time_lunar_phase_at_or_after/2`.

### Examples

    iex> Astro.Lunar.date_time_lunar_phase_at_or_after(738368, Astro.Lunar.full_moon_phase())
    738389.5013675035

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `date_time_lunar_phase_at_or_before`
*since 0.5.0* 

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

* `phase` is the required lunar phase expressed
  as a float number of degrees between `0.0` and
  `360.0`.

### Returns

* A `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Accuracy

The search ends within a millisecond of the crossing. Outside the
ephemeris the series place the phases within about 6 s RMS of JPL
over 1900–2100. See `Astro.date_time_lunar_phase_at_or_after/2`.

### Examples

    iex> Astro.Lunar.date_time_lunar_phase_at_or_before(738368, Astro.Lunar.new_moon_phase())
    738346.0532093873

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `date_time_new_moon_at_or_after`
*since 0.5.0* 

```elixir
@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.

A new moon is the moment the lunar phase, the Moon's apparent ecliptic
longitude minus the Sun's, passes 0°. It is found by refining the
estimate of `nth_new_moon/1` (Meeus, *Astronomical Algorithms*, chapter
49) to that crossing.

Raises `ArgumentError` for a moment more than 50,000 years from J2000.
Beyond about 75,000 years the chapter 49 estimates can be more than half
a month from the new moons, and a search could settle on a neighbouring
lunation's.

### Arguments

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* a `t:Astro.Time.moment/0` which is a float number of days
  since `0000-01-01`.

### Accuracy

Within a millisecond of the moment the phase passes 0°. Inside the
ephemeris this matches Meeus's correct time for the new moon of 18
February 1977 (example 49.a) to the second; outside it the series
place new moons within 6.0 s RMS of JPL over 1900–2100. See
`Astro.date_time_new_moon_before/1`.

### Examples

    iex> Astro.Lunar.date_time_new_moon_at_or_after(738390)
    738405.0359526364

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `date_time_new_moon_before`
*since 0.5.0* 

```elixir
@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.

A new moon is the moment the lunar phase, the Moon's apparent ecliptic
longitude minus the Sun's, passes 0°. It is found by refining the
estimate of `nth_new_moon/1` (Meeus, *Astronomical Algorithms*, chapter
49) to that crossing.

Raises `ArgumentError` for a moment more than 50,000 years from J2000.
Beyond about 75,000 years the chapter 49 estimates can be more than half
a month from the new moons, and a search could settle on a neighbouring
lunation's.

### Arguments

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* A `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Accuracy

Within a millisecond of the moment the phase passes 0°. Inside the
ephemeris this matches Meeus's correct time for the new moon of 18
February 1977 (example 49.a) to the second; outside it the series
place new moons within 6.0 s RMS of JPL over 1900–2100. See
`Astro.date_time_new_moon_before/1`.

### Examples

    iex> Astro.Lunar.date_time_new_moon_before 738390
    738375.5764820824

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `date_time_new_moon_nearest`
*since 2.0.0* 

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* a `t:Astro.Time.moment/0` which is a float number of days
  since `0000-01-01`.

### Accuracy

Within a millisecond of the moment the phase passes 0°. Inside the
ephemeris this matches Meeus's correct time for the new moon of 18
February 1977 (example 49.a) to the second; outside it the series
place new moons within 6.0 s RMS of JPL over 1900–2100. See
`Astro.date_time_new_moon_before/1`.

### Examples

    iex> Astro.Lunar.date_time_new_moon_nearest(738390)
    738375.5764820818

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `equatorial_horizontal_parallax`

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* The equatorial horizontal parallax as a float in degrees.

### Accuracy

It follows from the Moon's distance, which the series give within
2.9 km RMS of JPL; that changes it by under 0.03″.

### Examples

    iex> Astro.Lunar.equatorial_horizontal_parallax(738390)
    ...> |> Float.round(4)
    0.9586

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Lunar parallax](https://en.wikipedia.org/wiki/Lunar_parallax), Wikipedia.

# `first_quarter_phase`
*since 0.5.0* 

```elixir
@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

# `full_moon_phase`
*since 0.5.0* 

```elixir
@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

# `horizontal_dip`

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* The horizontal dip as a float in degrees. For the Moon it is
  usually slightly positive, because its parallax exceeds refraction
  and its semi-diameter together.

### Accuracy

It follows from the Moon's distance and the standard 34′ of
refraction; the refraction of the real atmosphere at the horizon
varies far more than the distance does.

### Examples

    iex> Astro.Lunar.horizontal_dip(Astro.Time.j2000()) |> Float.round(4)
    0.0941

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 15 (rising, transit and setting).

# `illuminated_fraction_of_moon`
*since 0.6.0* 

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* The fractional illumination of the Moon as a float
  between `0.0` (new moon) and `1.0` (full moon).

### Accuracy

For Meeus's example 48.a the result is 0.67856, against Meeus's
0.6786. Outside the ephemeris the series agree with JPL to 0.0000045
RMS over 1900–2100.

### Examples

    iex> Astro.Lunar.illuminated_fraction_of_moon(738390)
    ...> |> Float.round(4)
    0.9951

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 48 (illuminated fraction of the Moon's disk).

# `last_quarter_phase`
*since 0.5.0* 

```elixir
@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

# `lunar_altitude`
*since 0.4.0* 

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

* `location` is a `Geo.PointZ` struct with `{longitude, latitude, altitude}`
  coordinates.

### Returns

* The geocentric altitude in degrees, ranging from -180.0 to 180.0.

### Accuracy

As accurate as the Moon's position (see `lunar_position/1`). It is
geocentric and airless: seen from the Earth's surface the Moon is up
to about 1° lower, its parallax, and refraction raises it by about
34′ at the horizon.

### Examples

    iex> sydney = %Geo.PointZ{coordinates: {151.20666584, -33.8559799094, 0.0}}
    iex> Astro.Lunar.lunar_altitude(Astro.Time.j2000(), sydney) |> Float.round(4)
    -37.3277

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 13 (transformation of coordinates).

* [Horizontal coordinate system](https://en.wikipedia.org/wiki/Horizontal_coordinate_system), Wikipedia.

# `lunar_anomaly`

```elixir
@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

* `c` is the number of Julian centuries from J2000.0.

### Returns

* The mean lunar anomaly as a float in degrees.

### Accuracy

This is a mean element, not a position: a polynomial in time on
which the periodic terms of Meeus's chapter 47 series are built.
The positions the series give are within 2.7″ RMS of JPL in
longitude over 1900–2100; see `analytical_lunar_ecliptic_position/1`.

### Examples

    iex> Astro.Lunar.lunar_anomaly(0.0)
    134.9633964

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Mean anomaly](https://en.wikipedia.org/wiki/Mean_anomaly), Wikipedia.

# `lunar_distance`
*since 0.6.0* 

```elixir
@spec lunar_distance(t :: Astro.Time.moment()) :: Astro.meters()
```

Returns the Moon's distance from the Earth in meters for a given moment.

### Arguments

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* The Earth-Moon distance as a float in meters.

### Accuracy

From JPL inside the loaded ephemeris; elsewhere from the series,
within 2.9 km RMS and 11.7 km at most of JPL over 1900–2100.

### Examples

    iex> Astro.Lunar.lunar_distance(738390) |> trunc()
    381257780

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

# `lunar_elongation`

```elixir
@spec lunar_elongation(c :: Astro.Time.julian_centuries()) :: Astro.angle()
```

Returns the Moon's mean elongation from the Sun in degrees for a given
number of Julian centuries from J2000.0.

The mean elongation is the angle between the mean Moon and the mean
Sun (Meeus, *Astronomical Algorithms*, equation 47.2): 0° at a mean new
moon and 180° at a mean full moon.

### Arguments

* `c` is the number of Julian centuries from J2000.0.

### Returns

* The mean elongation as a float in degrees, in the range 0 to 360.

### Accuracy

This is a mean element, not a position: a polynomial in time on
which the periodic terms of Meeus's chapter 47 series are built.
The positions the series give are within 2.7″ RMS of JPL in
longitude over 1900–2100; see `analytical_lunar_ecliptic_position/1`.

### Examples

    iex> Astro.Lunar.lunar_elongation(0.0)
    297.8501921

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Elongation](https://en.wikipedia.org/wiki/Elongation_(astronomy)), Wikipedia.

# `lunar_latitude`
*since 0.6.0* 

```elixir
@spec lunar_latitude(Astro.Time.moment()) :: Astro.angle()
```

Returns the Moon's ecliptic latitude in degrees for a given moment.

### Arguments

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* The ecliptic latitude as a float in degrees.

### Accuracy

From JPL inside the loaded ephemeris; elsewhere from the series,
within 1.1″ RMS and 4.9″ at most of JPL over 1900–2100.

### Examples

    iex> Astro.Lunar.lunar_latitude(738390) |> Float.round(4)
    -5.0095

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

# `lunar_node`

```elixir
@spec lunar_node(t :: Astro.Time.moment()) :: Astro.angle()
```

Returns the angular distance of the Moon's node from the equinoctial
point in degrees for a given moment.

This is the Moon's argument of latitude, `moon_node/1`, reduced to the
range -90.0 to 90.0.

### Arguments

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* The angular distance as a float in degrees, from -90.0 to 90.0.

### Examples

    iex> Astro.Lunar.lunar_node(Astro.Time.j2000()) |> Float.round(6)
    -86.718131

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Lunar node](https://en.wikipedia.org/wiki/Lunar_node), Wikipedia.

# `lunar_phase_at`
*since 0.5.0* 

```elixir
@spec lunar_phase_at(t :: Astro.Time.moment()) :: Astro.angle()
```

Returns the lunar phase as a float number of degrees at
a given moment.

The phase is the Moon's apparent ecliptic longitude minus the Sun's,
reduced to the range 0 to 360: 0° at new moon, 90° at first quarter,
180° at full moon and 270° at last quarter.

### Arguments

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* the lunar phase as a float number of
  degrees.

### Accuracy

Outside the ephemeris the series agree with JPL over 1900–2100 to
2.8″ RMS and 11.5″ at most, about 6 s in the time a phase is
reached. See `Astro.lunar_phase_at/1`.

### Examples

    iex> Astro.Lunar.lunar_phase_at(738389.5007195644)
    179.99179178758195

    iex> Astro.Lunar.lunar_phase_at(738346.0544609067)
    0.014270322532084379

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Lunar phase](https://en.wikipedia.org/wiki/Lunar_phase), Wikipedia.

# `lunar_position`
*since 0.6.0* 

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

### Returns

* A 3-tuple `{right_ascension, declination, distance}` where
  right ascension and declination are in degrees and distance
  is in meters.

### Accuracy

From JPL inside the loaded ephemeris; elsewhere from
`analytical_lunar_position/1`, within 2.7″ RMS in right ascension and
1.3″ in declination of JPL over 1900–2100. See `Astro.moon_position_at/1`.

### Examples

    iex> {ra, _dec, _dist} = Astro.Lunar.lunar_position(738390)
    iex> Float.round(ra, 2)
    -19.96

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

# `lunar_radius`

```elixir
@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

# `lunation_at`
*since 2.10.0* 

```elixir
@spec lunation_at(Astro.Time.moment()) :: integer()
```

Returns the number of the lunation in progress at a moment.

Lunations are numbered as Meeus and NASA's eclipse catalogues number
them: lunation 0 begins with the new moon of 6 January 2000, and the
numbers before it are negative. A lunation begins at the new moon
estimated by the method of Meeus chapter 49, within 17 s of the
computed new moon over 1900–2100, 25 minutes at −2000 and four hours
at −10,000, so that close to a new moon the neighbouring lunation can
be returned.

The lunation is found by counting mean synodic months from that new
moon and stepping to the lunation whose estimated new moon is the
last at or before the moment, so the count holds for any date,
however far ΔT and the Moon's tidal deceleration move the new moons
from the mean.

### Arguments

* `t` is a `t:Astro.Time.moment/0`.

### Returns

* The lunation number, an integer.

### Examples

    iex> Astro.Lunar.lunation_at(Astro.Time.date_time_to_moment(~D[2000-01-07]))
    0

    iex> Astro.Lunar.lunation_at(Astro.Time.date_time_to_moment(~D[2024-04-15]))
    300

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `mean_lunar_ecliptic_longitude`

```elixir
@spec mean_lunar_ecliptic_longitude(c :: Astro.Time.julian_centuries()) ::
  Astro.angle()
```

Returns the Moon's mean longitude in degrees for a given number of
Julian centuries from J2000.0.

The mean longitude is where the Moon would be if it moved uniformly
along the ecliptic, measured from the equinox (Meeus, *Astronomical
Algorithms*, equation 47.1). It is the base to which the periodic terms
of the analytical series are added.

### Arguments

* `c` is the number of Julian centuries from J2000.0.

### Returns

* The mean longitude as a float in degrees, in the range 0 to 360.

### Accuracy

This is a mean element, not a position: a polynomial in time on
which the periodic terms of Meeus's chapter 47 series are built.
The positions the series give are within 2.7″ RMS of JPL in
longitude over 1900–2100; see `analytical_lunar_ecliptic_position/1`.

### Examples

    iex> Astro.Lunar.mean_lunar_ecliptic_longitude(0.0)
    218.3164477

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Mean longitude](https://en.wikipedia.org/wiki/Mean_longitude), Wikipedia.

# `moon_node`

```elixir
@spec moon_node(c :: Astro.Time.julian_centuries()) :: Astro.angle()
```

Returns the Moon's mean argument of latitude, its mean angular
distance from its ascending node, in degrees for a given number of
Julian centuries from J2000.0.

This is Meeus's *F* (Astronomical Algorithms, eq. 47.5), named
`moon-node` in Calendrical Calculations.

### Arguments

* `c` is the number of Julian centuries from J2000.0.

### Returns

* The mean argument of latitude as a float in degrees.

### Accuracy

This is a mean element, not a position: a polynomial in time on
which the periodic terms of Meeus's chapter 47 series are built.
The positions the series give are within 2.7″ RMS of JPL in
longitude over 1900–2100; see `analytical_lunar_ecliptic_position/1`.

### Examples

    iex> Astro.Lunar.moon_node(0.0)
    93.272095

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Argument of latitude](https://en.wikipedia.org/wiki/Argument_of_latitude), Wikipedia.

# `new_moon_day_before`
*since 2.10.0* 

```elixir
@spec new_moon_day_before(integer(), number() | (Astro.Time.moment() -&gt; number())) ::
  integer()
```

Returns the local day of the last new moon before the start of a
local day.

Calendars that count months from new moons need only the day on
which each falls, in the time they keep. This is the day, at the
offset in force when the new moon occurs, of the last new moon
before local midnight at the start of `day`: the same day as taking
`date_time_new_moon_before/1` at that midnight and reading its
local date, found faster.

The lunar phase always advances, at between 10° and 16° a day, so
one phase evaluated at a lunation's Meeus chapter 49 estimate places
its new moon within a narrow window. When the whole window falls on
one local day, that is the day; only a new moon near local midnight
is refined to its moment by `date_time_new_moon_before/1`'s search.

### Arguments

* `day` is a local day as an integer number of days since
  `0000-01-01`.

* `offset` is the local time's offset from UTC in days, as a number,
  or a 1-arity function that returns the offset for a moment, for a
  calendar whose time changes over its history.

### Returns

* the local day of the new moon as an integer number of days since
  `0000-01-01`.

Raises `ArgumentError` for a day more than 50,000 years from J2000.

### Accuracy

The same day as the moment search, whose new moons are within a
millisecond of the phase crossing; see `date_time_new_moon_before/1`.

### Examples

    iex> day = Date.to_gregorian_days(~D[2024-06-15])
    iex> Astro.Lunar.new_moon_day_before(day, 8 / 24) |> Date.from_gregorian_days()
    ~D[2024-06-06]

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `new_moon_day_on_or_after`
*since 2.10.0* 

```elixir
@spec new_moon_day_on_or_after(
  integer(),
  number() | (Astro.Time.moment() -&gt; number())
) :: integer()
```

Returns the local day of the first new moon at or after the start of
a local day.

The day, at the offset in force when the new moon occurs, of the
first new moon at or after local midnight at the start of `day`: the
same day as taking `date_time_new_moon_at_or_after/1` at that
midnight and reading its local date, found faster. See
`new_moon_day_before/2` for how.

### Arguments

* `day` is a local day as an integer number of days since
  `0000-01-01`.

* `offset` is the local time's offset from UTC in days, as a number,
  or a 1-arity function that returns the offset for a moment.

### Returns

* the local day of the new moon as an integer number of days since
  `0000-01-01`.

Raises `ArgumentError` for a day more than 50,000 years from J2000.

### Accuracy

The same day as the moment search; see
`date_time_new_moon_at_or_after/1`.

### Examples

    iex> day = Date.to_gregorian_days(~D[2024-06-15])
    iex> Astro.Lunar.new_moon_day_on_or_after(day, 8 / 24) |> Date.from_gregorian_days()
    ~D[2024-07-06]

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 49 (phases of the Moon).

# `new_moon_phase`
*since 0.5.0* 

```elixir
@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

# `solar_anomaly`

```elixir
@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

* `c` is the number of Julian centuries from J2000.0.

### Returns

* The mean solar anomaly as a float in degrees.

### Accuracy

This is a mean element, not a position: a polynomial in time on
which the periodic terms of Meeus's chapter 47 series are built.
The positions the series give are within 2.7″ RMS of JPL in
longitude over 1900–2100; see `analytical_lunar_ecliptic_position/1`.

### Examples

    iex> Astro.Lunar.solar_anomaly(0.0)
    357.5291092

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 47 (position of the Moon).

* [Mean anomaly](https://en.wikipedia.org/wiki/Mean_anomaly), Wikipedia.

# `topocentric_lunar_parallax`

```elixir
@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

* `t` is a `t:Astro.Time.moment/0` float number of days
  since `0000-01-01`.

* `location` is a `Geo.PointZ` struct with `{longitude, latitude, altitude}`
  coordinates.

### Returns

* The topocentric parallax as a float in degrees.

### Accuracy

It follows from the Moon's distance, which the series give within
2.9 km RMS of JPL; that changes it by under 0.03″.

### Examples

    iex> sydney = %Geo.PointZ{coordinates: {151.20666584, -33.8559799094, 0.0}}
    iex> Astro.Lunar.topocentric_lunar_parallax(Astro.Time.j2000(), sydney) |> Float.round(4)
    0.7221

### Reference

* Jean Meeus, *Astronomical Algorithms*, 2nd edition (1998),
  chapter 40 (correction for parallax).

* [Lunar parallax](https://en.wikipedia.org/wiki/Lunar_parallax), Wikipedia.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
