<p>The algorithm below produces the fraction of moon illumination based on the Julian Day (rather than the moon age).  It is from Meeus' <em>Astronomical Algorithms Second Edition</em> chapter 48.</p>
<p><span class="math-container">$$
\begin{align}
D &amp;= 297.8501921 + 445267.1114034T - 0.0018819T^2 + \frac{1}{545868.0}T^3 - \frac{1}{113065000.0}T^4 \\
M &amp;= 357.5291092 + 35999.0502909T - 0.0001536T^2 + \frac{1}{24490000.0}T^3 \\
M' &amp;= 134.9633964 + 477198.8675055T + 0.0087414T^2 + \frac{1}{69699}T^3 - \frac{1}{14712000.0}T^4 \\
i &amp;= 180 - D - 6.289 \sin M' + 2.1 \sin M -1.274 \sin(2D - M') -0.658 \sin 2D -0.214 \sin 2M' -0.11 \sin D \\
k &amp;= \frac{1 + \cos i}{2}
\end{align}
$$</span></p>
<p>Where <span class="math-container">$T$</span> is the number of Julian centuries since J2000: <span class="math-container">$T=(jd-2451545)/36525.0$</span>.  And <span class="math-container">$k$</span> is the fraction (from 0.0 to 1.0) of the moon (approximated as a perfect sphere) which is illuminated as viewed from the Geocenter.</p>
<p><span class="math-container">$D$</span>, <span class="math-container">$M$</span>, <span class="math-container">$M'$</span> are the Delaunay arguments.  Respectively the Moon's mean elongation, the Sun's mean anomaly, and the Moon's mean anomaly.</p>
<p>Here is an <a href="https://celestialprogramming.com/meeus-illuminated_fraction_of_the_moon.html" rel="noreferrer">example implementation in JavaScript</a>.</p>
<p>As far as an explanation of what all of the contants, etc mean... Sadly there is no deep dark secret explanation guarded by mythical creatures in funny hats who require you to solve puzzles to enter their chamber.  Rather, they're just a least squares fit to observations to find the coefficients <span class="math-container">$a_i$</span> of a function of the form:
<span class="math-container">$$
f(x) = a_1f_1(x) + a_2f_2(x) + a_2f_2(x) + ... a_if_i(x)
$$</span></p>
<p>For the Delaunay arguments, <span class="math-container">$f_i(x)$</span> are just the powers of <span class="math-container">$T$</span>.</p>
<p>For <span class="math-container">$i$</span> the <span class="math-container">$f_i(x)$</span> are trig functions of integer multiples of the Delaunay arguments.  This method has been used in many ephemeris algorithms, most notably <a href="https://adsabs.harvard.edu/full/1988A%26A...202..309B" rel="noreferrer">VSOP87</a>.  Again, it might seem like there's a deep scientific method involved in figuring out which ones to use.  But as described in &quot;<a href="https://www.aanda.org/articles/aa/abs/2006/35/aa4941-06/aa4941-06.html" rel="noreferrer">Synthetic representation of the Galilean satellites' orbital motions from L1 ephemerides</a>&quot;, it's largely a matter of performing a Fourier transform to find good candidates, then trying almost every integer multiple of each argument and just picking the one which fits the observations best.  Which solution to pick is largely a balance between computational complexity and accuracy over a desired time frame.</p>

CC BY-SA 4.0
2023-04-06T17:58:48.200Z
Despite being disappointed by the lack of involvement of mythical creatures, thank you very much for the explanation! And for adding some more info on your web site. It would have taken me enormous amout of time to implement based on the theory.
akostadinov
CC BY-SA 4.0
2023-04-07T08:23:04.627Z
Can I check -  the T³ and T⁴  I would expect them to be in the numerator of the fractions, not the denominator.  Are the formulas correct?  Is that a typo?
James K
CC BY-SA 4.0
2023-04-07T13:21:47.253Z
@JamesK  You're correct, thanks.  I have edited the post.
Greg Miller
CC BY-SA 4.0
2023-04-07T23:09:03.230Z
Well pointed out! Jean Meeus's clever shortcut formulae for the illuminated fraction of the moon's disk deserve to be better known, I think. It might also be worth mentioning (because occasionally people express doubts about it), that the illuminated fraction of the *diameter* (taken to cut the crescent etc halfway between the moon's 'horns') is the same as the illuminated fraction of the *disk area* because the crescent is of ellipse form and the projection of circle on to ellipse preserves such area-ratios. It's a good algorithm.
terry-s
CC BY-SA 4.0
2023-04-06T14:37:27.093Z
2023-04-07T13:21:18.110Z
2023-04-07T13:21:18.110Z
Greg Miller
<p>trying to compute moon illumination percent from moon day.</p>
<p>To get moon day in pseudo code I do:</p>
<pre><code>LUNAR_MONTH = 29.530588853
KNOWN_NEW_MOON = JulianDay(&quot;2000-01-06 06:14&quot;)
age = (julian_day_now - KNOWN_NEW_MOON).abs % LUNAR_MONTH
</code></pre>
<p>So that shows me right now an age of 10.9 days. How do I tell percent illumination?</p>
<ul>
<li>PS I've got the above way to calculate moon age from <a href="https://en.wikipedia.org/wiki/Lunar_phase#Calculating_phase" rel="noreferrer">wikipedia</a>.</li>
<li>PPS Actual Ruby code to do so is in <a href="https://stackoverflow.com/q/74987538/520567">https://stackoverflow.com/q/74987538/520567</a></li>
</ul>

CC BY-SA 4.0
2023-01-02T23:57:57.863Z
The Moon's angular speed varies a fair bit, so that age calculation is just a rough approximation.
PM 2Ring
CC BY-SA 4.0
2023-01-03T00:18:32.157Z
This computes the moon illumination given a date: https://celestialprogramming.com/meeus-illuminated_fraction_of_the_moon.html
Greg Miller
CC BY-SA 4.0
2023-01-03T08:58:00.547Z
There is a related question, but I hesitate to mark as duplicate, since the answer their depends on external spreadsheets that are no longer available.  This rough and ready estimation of the phase can be done by simple trig, assuming (as you do) that the moon/s orbit is simple and circular.  https://astronomy.stackexchange.com/questions/1709/formulas-to-determine-the-illuminated-phase-and-orientation-of-the-moon
James K
CC BY-SA 4.0
2023-01-03T10:35:55.937Z
@GregMiller, glad that you see my question! I would be happy if you can answer my question on stackoverflow. I saw your page but I have no idea what it does. `const T=(jd-2451545)/36525.0;` - what is this? Lets assume I don't care so much to understand all other constants but I'd like to calculate this according to the method I use to get julian day. Otherwise I'm not sure whether my julian day is same as yours.
akostadinov
CC BY-SA 4.0
2023-01-03T17:22:55.013Z
@akostadinov, that line computes the number of Julian centuries since J2000.  The "jd" is the standard Julian date, and the big number is the Julian date for Jan 1, 2000.  The linked page also has routines for computing the Julian date, so you can use those if you're concerned.
Greg Miller
CC BY-SA 4.0
2023-01-04T01:03:12.493Z
Thank you @GregMiller! You can see my stackoverflow question for my implementation. I see that full moon is given on Jan 6 23:09 on mooninfo.org while my computation returns at 11:05. Is this an expected margin of error or do you think I messed up something?
akostadinov
CC BY-SA 4.0
2023-01-04T01:11:35.797Z
Actually around 12 hours difference from mooninfo.org, also for 2000-08-15. Either I have someting wrong, or algorithm is a little off or mooninfo.org are off.
akostadinov
CC BY-SA 4.0
2023-01-04T05:30:05.523Z
You probably didn't account for a Julian day starting an 12:00 noon rather than midnight.
Greg Miller
CC BY-SA 4.0
2023-01-04T10:55:40.293Z
@GregMiller, that's true! I get it at `00:00`, not noon. Now I'm within 4 minutes accuracy compared with mooninfo.org for the next full moon. While this accounts for the inaccuracy, there is still something unclear about your `jd` calculation for me. `DateTime.new(2000, 1, 1, 12, 0, 0).ajd.to_f => 2451545.0` as in your code. But if I get a unix timestamp of it, then use your formula I get a very different result: `DateTime.new(2000, 1, 1, 12, 0, 0).to_time.to_i / 86400000 + 2440587.5 => 2440597.5`. Do you have an explanation to this?
akostadinov
CC BY-SA 4.0
2023-01-04T11:31:46.463Z
@GregMiller, also if you post an answer, I will be glad to accept it because basically that did the job for me.
akostadinov
CC BY-SA 4.0
2023-03-28T13:15:53.493Z
@GregMiller, another question. You perform `angle = num % 360` then `angle += 360 if angle.negative?`. Which definition of modulo should be used? Ruby has a `floored` modulo and it seems to be what we need here. But wanted to double check as I'm not familiar with the math you're using.
akostadinov
CC BY-SA 4.0
2023-03-28T15:27:42.700Z
@akostadinov, I'm not familiar with Ruby's floor modulo, so can't say for sure.  The goal there is just to make sure the value is in the range from 0 to 360.  For your question about the timestamp above, it looks like the function you're using isn't returning a Unix timestamp, so you can't use that method.
Greg Miller
CC BY-SA 4.0
2023-03-28T16:44:30.913Z
@GregMiller, it is returning a unix timestamp. `DateTime.new(2000, 1, 1, 12, 0, 0).to_time.to_i => 946728000`, then in shell `$ TZ=UTC date -d "@946728000" => 1.01.2000 (сб) 12:00:00 UTC`.
akostadinov
CC BY-SA 4.0
2023-03-28T16:49:51.773Z
Ok, got it. Need to divide by float `86400.0`, then I get `2451545.0`. Maybe in your code the timestamp is milliseconds and not seconds like in my case. Good that things are cleared up. That was interesting. Sad only in comments.
akostadinov
CC BY-SA 4.0
2023-04-05T03:31:44.650Z
@akostadinov I added a bounty to attract an answer. If it turns out you've solved the problem and feel up to writing it up as an answer, please feel free to do so.
uhoh
CC BY-SA 4.0
2023-04-05T09:12:13.703Z
How about the Daft Moon application? It does it for free hour-by-hour
Geographos
CC BY-SA 4.0
2023-04-05T14:17:26.677Z
@uhoh, I didn't post a solution here because I've got (and needed) a computer algorithm. That I've got and posted to stackoverflow. Also Greg has such in another language. I think an answer worth this site would be more theoretical math how to do it and not just pasting a magic algorithm that works reasonably well. I will be interested to see such an answer. Also referring to some app and not explaining how it works is also a non-answer imho.
akostadinov
<moon-phases>
Calculate moon illumination given moon age
akostadinov
# Calculate moon illumination given moon age

(Asked by: username_0 on 2023-01-02)

trying to compute moon illumination percent from moon day.
To get moon day in pseudo code I do:
LUNAR_MONTH = 29.530588853
KNOWN_NEW_MOON = JulianDay("2000-01-06 06:14")
age = (julian_day_now - KNOWN_NEW_MOON).abs % LUNAR_MONTH

So that shows me right now an age of 10.9 days. How do I tell percent illumination?

PS I've got the above way to calculate moon age from wikipedia.
PPS Actual Ruby code to do so is in https://stackoverflow.com/q/74987538/520567

**Tags:** moon-phases
> **Comments:**
> **username_1**: The Moon's angular speed varies a fair bit, so that age calculation is just a rough approximation.  
> **username_2**: This computes the moon illumination given a date: https://celestialprogramming.com/meeus-illuminated_fraction_of_the_moon.html  
> **username_3**: There is a related question, but I hesitate to mark as duplicate, since the answer their depends on external spreadsheets that are no longer available.  This rough and ready estimation of the phase can be done by simple trig, assuming (as you do) that the moon/s orbit is simple and circular.  https://astronomy.stackexchange.com/questions/1709/formulas-to-determine-the-illuminated-phase-and-orientation-of-the-moon  
> **username_0**: @GregMiller, glad that you see my question! I would be happy if you can answer my question on stackoverflow. I saw your page but I have no idea what it does. `const T=(jd-2451545)/36525.0;` - what is this? Lets assume I don't care so much to understand all other constants but I'd like to calculate this according to the method I use to get julian day. Otherwise I'm not sure whether my julian day is same as yours.  
> **username_2**: @akostadinov, that line computes the number of Julian centuries since J2000.  The "jd" is the standard Julian date, and the big number is the Julian date for Jan 1, 2000.  The linked page also has routines for computing the Julian date, so you can use those if you're concerned.  
> **username_0**: Thank you @GregMiller! You can see my stackoverflow question for my implementation. I see that full moon is given on Jan 6 23:09 on mooninfo.org while my computation returns at 11:05. Is this an expected margin of error or do you think I messed up something?  
> **username_0**: Actually around 12 hours difference from mooninfo.org, also for 2000-08-15. Either I have someting wrong, or algorithm is a little off or mooninfo.org are off.  
> **username_2**: You probably didn't account for a Julian day starting an 12:00 noon rather than midnight.  
> **username_0**: @GregMiller, that's true! I get it at `00:00`, not noon. Now I'm within 4 minutes accuracy compared with mooninfo.org for the next full moon. While this accounts for the inaccuracy, there is still something unclear about your `jd` calculation for me. `DateTime.new(2000, 1, 1, 12, 0, 0).ajd.to_f => 2451545.0` as in your code. But if I get a unix timestamp of it, then use your formula I get a very different result: `DateTime.new(2000, 1, 1, 12, 0, 0).to_time.to_i / 86400000 + 2440587.5 => 2440597.5`. Do you have an explanation to this?  
> **username_0**: @GregMiller, also if you post an answer, I will be glad to accept it because basically that did the job for me.  
> **username_0**: @GregMiller, another question. You perform `angle = num % 360` then `angle += 360 if angle.negative?`. Which definition of modulo should be used? Ruby has a `floored` modulo and it seems to be what we need here. But wanted to double check as I'm not familiar with the math you're using.  
> **username_2**: @akostadinov, I'm not familiar with Ruby's floor modulo, so can't say for sure.  The goal there is just to make sure the value is in the range from 0 to 360.  For your question about the timestamp above, it looks like the function you're using isn't returning a Unix timestamp, so you can't use that method.  
> **username_0**: @GregMiller, it is returning a unix timestamp. `DateTime.new(2000, 1, 1, 12, 0, 0).to_time.to_i => 946728000`, then in shell `$ TZ=UTC date -d "@946728000" => 1.01.2000 (сб) 12:00:00 UTC`.  
> **username_0**: Ok, got it. Need to divide by float `86400.0`, then I get `2451545.0`. Maybe in your code the timestamp is milliseconds and not seconds like in my case. Good that things are cleared up. That was interesting. Sad only in comments.  
> **username_4**: @akostadinov I added a bounty to attract an answer. If it turns out you've solved the problem and feel up to writing it up as an answer, please feel free to do so.  
> **username_5**: How about the Daft Moon application? It does it for free hour-by-hour  
> **username_0**: @uhoh, I didn't post a solution here because I've got (and needed) a computer algorithm. That I've got and posted to stackoverflow. Also Greg has such in another language. I think an answer worth this site would be more theoretical math how to do it and not just pasting a magic algorithm that works reasonably well. I will be interested to see such an answer. Also referring to some app and not explaining how it works is also a non-answer imho.  

---

## 1 answers

### Answer by username_2 on 2023-04-06. Score: 10 | Accepted answer

The algorithm below produces the fraction of moon illumination based on the Julian Day (rather than the moon age). It is from Meeus' *Astronomical Algorithms Second Edition* chapter 48.

$$
\begin{align}
D &= 297.8501921 + 445267.1114034T - 0.0018819T^2 + \frac{1}{545868.0}T^3 - \frac{1}{113065000.0}T^4 \\
M &= 357.5291092 + 35999.0502909T - 0.0001536T^2 + \frac{1}{24490000.0}T^3 \\
M' &= 134.9633964 + 477198.8675055T + 0.0087414T^2 + \frac{1}{69699}T^3 - \frac{1}{14712000.0}T^4 \\
i &= 180 - D - 6.289 \sin M' + 2.1 \sin M -1.274 \sin(2D - M') -0.658 \sin 2D -0.214 \sin 2M' -0.11 \sin D \\
k &= \frac{1 + \cos i}{2}
\end{align}
$$

Where $T$ is the number of Julian centuries since J2000: $T=(jd-2451545)/36525.0$. And $k$ is the fraction (from 0.0 to 1.0) of the moon (approximated as a perfect sphere) which is illuminated as viewed from the Geocenter.

$D$, $M$, $M'$ are the Delaunay arguments. Respectively the Moon's mean elongation, the Sun's mean anomaly, and the Moon's mean anomaly.

Here is an [example implementation in JavaScript](https://celestialprogramming.com/meeus-illuminated_fraction_of_the_moon.html).

As far as an explanation of what all of the contants, etc mean... Sadly there is no deep dark secret explanation guarded by mythical creatures in funny hats who require you to solve puzzles to enter their chamber. Rather, they're just a least squares fit to observations to find the coefficients $a\_i$ of a function of the form:
$$
f(x) = a\_1f\_1(x) + a\_2f\_2(x) + a\_2f\_2(x) + ... a\_if\_i(x)
$$

For the Delaunay arguments, $f\_i(x)$ are just the powers of $T$.

For $i$ the $f\_i(x)$ are trig functions of integer multiples of the Delaunay arguments. This method has been used in many ephemeris algorithms, most notably [VSOP87](https://adsabs.harvard.edu/full/1988A%26A...202..309B). Again, it might seem like there's a deep scientific method involved in figuring out which ones to use. But as described in "[Synthetic representation of the Galilean satellites' orbital motions from L1 ephemerides](https://www.aanda.org/articles/aa/abs/2006/35/aa4941-06/aa4941-06.html)", it's largely a matter of performing a Fourier transform to find good candidates, then trying almost every integer multiple of each argument and just picking the one which fits the observations best. Which solution to pick is largely a balance between computational complexity and accuracy over a desired time frame.

> **Comments:**
> **username_0**: Despite being disappointed by the lack of involvement of mythical creatures, thank you very much for the explanation! And for adding some more info on your web site. It would have taken me enormous amout of time to implement based on the theory.  
> **username_3**: Can I check -  the T³ and T⁴  I would expect them to be in the numerator of the fractions, not the denominator.  Are the formulas correct?  Is that a typo?  
> **username_2**: @JamesK  You're correct, thanks.  I have edited the post.  
> **username_6**: Well pointed out! Jean Meeus's clever shortcut formulae for the illuminated fraction of the moon's disk deserve to be better known, I think. It might also be worth mentioning (because occasionally people express doubts about it), that the illuminated fraction of the *diameter* (taken to cut the crescent etc halfway between the moon's 'horns') is the same as the illuminated fraction of the *disk area* because the crescent is of ellipse form and the projection of circle on to ellipse preserves such area-ratios. It's a good algorithm.  

---

