Skip to content

Commit 438cb4d

Browse files
committed
Added new moon phase calculator recipe.
1 parent 10cd982 commit 438cb4d

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
---
2+
layout: recipe
3+
title: Calculate Phase of the Moon for a Date
4+
chapter: Dates and Times
5+
---
6+
## Problem
7+
8+
You want to find the current phase of the moon.
9+
10+
## Solution
11+
12+
The following code provides a method to calcualate the phase of the moon for a given date.
13+
14+
{% highlight coffeescript %}
15+
# moonPhase.coffee
16+
17+
# Moon-phase calculator
18+
# Roger W. Sinnott, Sky & Telescope, June 16, 2006
19+
# http://www.skyandtelescope.com/observing/objects/javascript/moon_phases
20+
#
21+
# Translated to CoffeeScript by Mike Hatfield @WebCoding4Fun
22+
23+
proper_ang = (big) ->
24+
tmp = 0
25+
if big > 0
26+
tmp = big / 360.0
27+
tmp = (tmp - (~~tmp)) * 360.0
28+
else
29+
tmp = Math.ceil(Math.abs(big / 360.0))
30+
tmp = big + tmp * 360.0
31+
32+
tmp
33+
34+
jdn = (date) ->
35+
month = date.getMonth()
36+
day = date.getDate()
37+
year = date.getFullYear()
38+
zone = date.getTimezoneOffset() / 1440
39+
40+
mm = month
41+
dd = day
42+
yy = year
43+
44+
yyy = yy
45+
mmm = mm
46+
if mm < 3
47+
yyy = yyy - 1
48+
mmm = mm + 12
49+
50+
day = dd + zone + 0.5
51+
a = ~~( yyy / 100 )
52+
b = 2 - a + ~~( a / 4 )
53+
jd = ~~( 365.25 * yyy ) + ~~( 30.6001 * ( mmm+ 1 ) ) + day + 1720994.5
54+
jd + b if jd > 2299160.4999999
55+
56+
moonElong = (jd) ->
57+
dr = Math.PI / 180
58+
rd = 1 / dr
59+
meeDT = Math.pow((jd - 2382148), 2) / (41048480 * 86400)
60+
meeT = (jd + meeDT - 2451545.0) / 36525
61+
meeT2 = Math.pow(meeT, 2)
62+
meeT3 = Math.pow(meeT, 3)
63+
meeD = 297.85 + (445267.1115 * meeT) - (0.0016300 * meeT2) + (meeT3 / 545868)
64+
meeD = (proper_ang meeD) * dr
65+
meeM1 = 134.96 + (477198.8676 * meeT) + (0.0089970 * meeT2) + (meeT3 / 69699)
66+
meeM1 = (proper_ang meeM1) * dr
67+
meeM = 357.53 + (35999.0503 * meeT)
68+
meeM = (proper_ang meeM) * dr
69+
70+
elong = meeD * rd + 6.29 * Math.sin( meeM1 )
71+
elong = elong - 2.10 * Math.sin( meeM )
72+
elong = elong + 1.27 * Math.sin( 2*meeD - meeM1 )
73+
elong = elong + 0.66 * Math.sin( 2*meeD )
74+
elong = proper_ang elong
75+
elong = Math.round elong
76+
77+
moonNum = ( ( elong + 6.43 ) / 360 ) * 28
78+
moonNum = ~~( moonNum )
79+
80+
if moonNum is 28 then 0 else moonNum
81+
82+
getMoonPhase = (age) ->
83+
moonPhase = "new Moon"
84+
moonPhase = "first quarter" if age > 3 and age < 11
85+
moonPhase = "full Moon" if age > 10 and age < 18
86+
moonPhase = "last quarter" if age > 17 and age < 25
87+
88+
if ((age is 1) or (age is 8) or (age is 15) or (age is 22))
89+
moonPhase = "1 day past " + moonPhase
90+
91+
if ((age is 2) or (age is 9) or (age is 16) or (age is 23))
92+
moonPhase = "2 days past " + moonPhase
93+
94+
if ((age is 3) or (age is 1) or (age is 17) or (age is 24))
95+
moonPhase = "3 days past " + moonPhase
96+
97+
if ((age is 4) or (age is 11) or (age is 18) or (age is 25))
98+
moonPhase = "3 days before " + moonPhase
99+
100+
if ((age is 5) or (age is 12) or (age is 19) or (age is 26))
101+
moonPhase = "2 days before " + moonPhase
102+
103+
if ((age is 6) or (age is 13) or (age is 20) or (age is 27))
104+
moonPhase = "1 day before " + moonPhase
105+
106+
moonPhase
107+
108+
MoonPhase = exports? and exports or @MoonPhase = {}
109+
110+
class MoonPhase.Calculator
111+
getMoonDays: (date) ->
112+
jd = jdn date
113+
moonElong jd
114+
115+
getMoonPhase: (date) ->
116+
jd = jdn date
117+
getMoonPhase( moonElong jd )
118+
{% endhighlight %}
119+
120+
## Discussion
121+
122+
This code exposes a MoonPhase Calculator object with two methods. Calculator -> getMoonPhase will return a text representation of the lunar phase for the date provided.
123+
124+
This can be used in both the browser and Node.js.
125+
126+
{% highlight console %}
127+
$ node
128+
> var MoonPhase = require('./moonPhase.js');
129+
undefined
130+
> var calc = new MoonPhase.Calculator();
131+
undefined
132+
> calc.getMoonPhase(new Date());
133+
'full moon'
134+
> calc.getMoonPhase(new Date(1972, 6, 30));
135+
'3 days before last quarter'
136+
{% endhighlight %}

0 commit comments

Comments
 (0)