## Problem
You want to find the current phase of the moon.
## Solution
The following code provides a method to calcualate the phase of the moon for a given date.
~~~
# moonPhase.coffee
# Moon-phase calculator
# Roger W. Sinnott, Sky & Telescope, June 16, 2006
# http://www.skyandtelescope.com/observing/objects/javascript/moon_phases
#
# Translated to CoffeeScript by Mike Hatfield @WebCoding4Fun
proper_ang = (big) ->
tmp = 0
if big > 0
tmp = big / 360.0
tmp = (tmp - (~~tmp)) * 360.0
else
tmp = Math.ceil(Math.abs(big / 360.0))
tmp = big + tmp * 360.0
tmp
jdn = (date) ->
month = date.getMonth()
day = date.getDate()
year = date.getFullYear()
zone = date.getTimezoneOffset() / 1440
mm = month
dd = day
yy = year
yyy = yy
mmm = mm
if mm < 3
yyy = yyy - 1
mmm = mm + 12
day = dd + zone + 0.5
a = ~~( yyy / 100 )
b = 2 - a + ~~( a / 4 )
jd = ~~( 365.25 * yyy ) + ~~( 30.6001 * ( mmm+ 1 ) ) + day + 1720994.5
jd + b if jd > 2299160.4999999
moonElong = (jd) ->
dr = Math.PI / 180
rd = 1 / dr
meeDT = Math.pow((jd - 2382148), 2) / (41048480 * 86400)
meeT = (jd + meeDT - 2451545.0) / 36525
meeT2 = Math.pow(meeT, 2)
meeT3 = Math.pow(meeT, 3)
meeD = 297.85 + (445267.1115 * meeT) - (0.0016300 * meeT2) + (meeT3 / 545868)
meeD = (proper_ang meeD) * dr
meeM1 = 134.96 + (477198.8676 * meeT) + (0.0089970 * meeT2) + (meeT3 / 69699)
meeM1 = (proper_ang meeM1) * dr
meeM = 357.53 + (35999.0503 * meeT)
meeM = (proper_ang meeM) * dr
elong = meeD * rd + 6.29 * Math.sin( meeM1 )
elong = elong - 2.10 * Math.sin( meeM )
elong = elong + 1.27 * Math.sin( 2*meeD - meeM1 )
elong = elong + 0.66 * Math.sin( 2*meeD )
elong = proper_ang elong
elong = Math.round elong
moonNum = ( ( elong + 6.43 ) / 360 ) * 28
moonNum = ~~( moonNum )
if moonNum is 28 then 0 else moonNum
getMoonPhase = (age) ->
moonPhase = "new Moon"
moonPhase = "first quarter" if age > 3 and age < 11
moonPhase = "full Moon" if age > 10 and age < 18
moonPhase = "last quarter" if age > 17 and age < 25
if ((age is 1) or (age is 8) or (age is 15) or (age is 22))
moonPhase = "1 day past " + moonPhase
if ((age is 2) or (age is 9) or (age is 16) or (age is 23))
moonPhase = "2 days past " + moonPhase
if ((age is 3) or (age is 1) or (age is 17) or (age is 24))
moonPhase = "3 days past " + moonPhase
if ((age is 4) or (age is 11) or (age is 18) or (age is 25))
moonPhase = "3 days before " + moonPhase
if ((age is 5) or (age is 12) or (age is 19) or (age is 26))
moonPhase = "2 days before " + moonPhase
if ((age is 6) or (age is 13) or (age is 20) or (age is 27))
moonPhase = "1 day before " + moonPhase
moonPhase
MoonPhase = exports? and exports or @MoonPhase = {}
class MoonPhase.Calculator
getMoonDays: (date) ->
jd = jdn date
moonElong jd
getMoonPhase: (date) ->
jd = jdn date
getMoonPhase( moonElong jd )
~~~
## Discussion
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.
This can be used in both the browser and Node.js.
~~~
$ node
> var MoonPhase = require('./moonPhase.js');
undefined
> var calc = new MoonPhase.Calculator();
undefined
> calc.getMoonPhase(new Date());
'full moon'
> calc.getMoonPhase(new Date(1972, 6, 30));
'3 days before last quarter'
~~~
- 贡献
- 作者
- 授权协议
- 1、Syntax
- 在服务端和客户端重用代码
- For循环
- 嵌入JavaScript代码
- 值域
- 2、Classes and Objects
- 类方法和实例方法
- CoffeeScript式的Type函数
- 链式调用
- 克隆对象(深度克隆)
- 不存在就赋值为对象字面量
- 类变量
- 3、Strings
- 分割字符串
- 字符串匹配
- 查找子字符串
- 让整个字符串小写
- 大写整个字符
- 去掉字符串首尾的空白
- 生成唯一的ID
- 首字母大写
- 重复字符串
- 字符串插值
- 4、Arrays
- Python式的Zip函数 Python-like Zip Function
- 数组去重 Removing Duplicate Elements from Arrays
- 基于数组构建字典对象 Creating a dictionary Object from an Array
- 数组转成字符串 Creating a String from an Array
- 检查每一个元素 Testing Every Element
- 数组最大值
- 过滤数组 Filtering Arrays
- 定义区间数组 Define Ranges Array
- 转置数组 Reversing Arrays
- 化简数组 Reducing Arrays
- 使用数组来做值交换 Using Arrays to Swap Variables
- 列表解析 List Comprehensions
- 检查值的类型是否是数组
- 连接数组
- 搅乱数组中的元素 Shuffling Array Elements
- 数组映射 Mapping Arrays
- 5、Dates and Times
- Calculate Phase of the Moon for a Date
- 找出某月的最后一天是几号 Finding the Last Day of the Month
- 获取两个日期相差的天数 Get Days Between Two Dates
- 计算复活节岛日期 Calculate the Date of Easter Sunday
- 计算感恩节的日期(美国和加拿大) Calculate the Date of Thanksgiving (USA and Canada)
- 计算上一个(下一个)月份 Finding Last (or Next) Month
- 6、Math
- 快速逆平方根
- 一个随机整数的函数
- 更快的斐波那契算法
- 生成可预测的随机数
- 弧度与度转换
- 生成随机数
- 数学常数
- 7、Functions
- 反抖动函数 Debounce Functions
- 参数数组化 Splat Arguments
- 当函数调用的括号不可以省略时 When Function Parentheses Are Not Optional
- 递归函数 Recursive Functions
- 8、Metaprogramming
- 扩展内置对象 Extending Built-in Objects
- 检测并创建缺失的函数 Detecting and Creating Missing Functions
- 9、jQuery
- 回调绑定
- 创建jQuery插件
- AJAX
- 10、Ajax
- 不依赖jQuery的Ajax请求 Ajax Request Without jQuery
- 11、Regular Expressions
- 替换子字符串 Replacing Substrings
- 使用定点 Using Heregexes
- 使用HTML字符实体替换HTML标签 Replacing HTML Tags with HTML Named Entities
- 搜索子字符串 Searching for Substrings
- 12、Networking
- 简单的服务器
- 双向客户端
- 最简单的HTTP客户端
- 最简单的HTTP服务器
- 简单的客户端
- 双向服务端 Bi-Directional Server
- 13、Design Patterns
- 命令模式
- 单例模式
- 策略模式 Strategy Pattern
- 建造者模式 Builder Pattern
- 备忘录模式 Memento Pattern
- 解释器模式 Interpreter Pattern
- 装饰者模式
- 桥接模式
- 工厂方法模式
- 14、Databases
- MongoDB
- SQLite
- 15、Testing
- 使用Jasmine测试