月齢計算

 月齢自体にはあまり興味はなかったんだけど、月以外の天体写真を撮っていてその時の月の状態によって空のコンディションが変わり撮れる写真に大きな違いが生まれる。
 特に天体写真を撮るためにスケジュールを定める際には、休みの日の月の状態が必要になる。遠征を検討するようになってなるだけ手軽にその時の月齢を知りたくなって調べてみた。

 まず、月齢とは朔(新月)の瞬間からの経過日数であるということ。月齢何日が満月だという定義はなく概ね13日から15日に満月に当たる瞬間があるということ。まぁ、月の軌道は概ね楕円軌道であるがいろいろな条件で軌道が変化するために朔から朔までの日数は変化するので満月である月齢も変わってくるという。
 概ねの月の周期は分かっているのである朔の日付時刻が分かれば有る瞬間の月齢は大まかに計算できる。たぶん、私が必要とする計算はこの程度で十分だけど、起点とする朔の日付から計算する瞬間が離れれば離れるほど誤差も拡大すると思われる。
 いろいろ調べて行ったら厳密に月の周期毎の朔の日付時刻を出しているページを見つけた。
 これは国立天文台国立天文台天文情報センター暦計算室のページの中にある暦要項の朔弦望のページ。
 ここには太陽と月の角度が0度、90度、180度、270度になる瞬間の時刻が本年と前後2年分載っている。朔(新月)、上弦、満月、下弦である。
 計算で必要となるのは朔の瞬間だけですが。

 で、朔の日付時刻のデータ列をExcelに喰わせてみて、ついでにVBAを書いて、ある任意の瞬間の月齢を出すようにして見た。Excelの日付時刻型の数値は一日を1とした数値になっているのは好都合である。
 ある瞬間の月齢を出そうとしたらその瞬間の日付時刻から直近の朔の日付時刻を引けばそのまま月齢が出るという形になる。
 で、入手した最小の朔の日付よりも小さい日付時刻が入力されたり最大の朔の日付より大きくなった場合には基準と出来る日付時刻と平均の周期と言われている数字を使って算出するようにした。

 朔の日付時刻データ。sheet名は「saku」。

2007/1/19 13:01
2007/2/18 1:14
2007/3/19 11:43
2007/4/17 20:36
2007/5/17 4:27
2007/6/15 12:13
2007/7/14 21:04
2007/8/13 8:03
2007/9/11 21:44
2007/10/11 14:01
2007/11/10 8:03
2007/12/10 2:40
2008/1/8 20:37
2008/2/7 12:45
2008/3/8 2:14
2008/4/6 12:55
2008/5/5 21:18
2008/6/4 4:23
2008/7/3 11:19
2008/8/1 19:13
2008/8/31 4:58
2008/9/29 17:12
2008/10/29 8:14
2008/11/28 1:55
2008/12/27 21:22
2009/1/26 16:55
2009/2/25 10:35
2009/3/27 1:06
2009/4/25 12:23
2009/5/24 21:11
2009/6/23 4:35
2009/7/22 11:35
2009/8/20 19:02
2009/9/19 3:44
2009/10/18 14:33
2009/11/17 4:14
2009/12/16 21:02

で、VBAのプログラム。

Function getsurei(indt As Date) As Double
Dim ws As Worksheet

Set ws = Worksheets("saku")
i = 1
dt = 29.530589

Do
    If IsEmpty(ws.Range("A" & Format(i))) Then
        getsurei = indt - (ws.Range("A" & Format(i - 1)).Value + Int((indt - ws.Range("A" & Format(i - 1)).Value) / dt) * dt)
        Exit Do
    End If
    If ws.Range("A" & Format(i)).Value > indt Then
        If i = 1 Then
            getsurei = indt - (ws.Range("A1").Value - (Int((ws.Range("A1").Value - indt) / dt) + 1) * dt)
        Else
            getsurei = indt - ws.Range("A" & Format(i - 1)).Value
        End If
        Exit Do
    End If
    i = i + 1
Loop

End Function

 あまり検証していないので前後の処理におかしなところがあるかもしれない。その時は優しく教えてほしい。
 遠征スケジュールを調べるには無駄に正確な値が出てくるが、この辺のアンバランスさがマニアとしての証明になるのかもしれない。