mk_calendar 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +11 -31
- data/exe/mk_calendar +17 -19
- data/lib/mk_calendar/calendar.rb +35 -1086
- data/lib/mk_calendar/compute.rb +1033 -0
- data/lib/mk_calendar/version.rb +1 -1
- data/lib/mk_calendar.rb +3 -2
- metadata +3 -2
@@ -0,0 +1,1033 @@
|
|
1
|
+
module MkCalendar
|
2
|
+
module Compute
|
3
|
+
module_function
|
4
|
+
|
5
|
+
#=========================================================================
|
6
|
+
# 休日の計算
|
7
|
+
#
|
8
|
+
# @param: year
|
9
|
+
# @param: month
|
10
|
+
# @param: day
|
11
|
+
# @return: holiday (漢字1文字)
|
12
|
+
#=========================================================================
|
13
|
+
def compute_holiday(year, month, day)
|
14
|
+
holiday_0 = Array.new # 変動の祝日用
|
15
|
+
holiday_1 = Array.new # 国民の休日用
|
16
|
+
holiday_2 = Array.new # 振替休日用
|
17
|
+
|
18
|
+
# 変動の祝日の日付・曜日を計算 ( 振替休日,国民の休日を除く )
|
19
|
+
Const::HOLIDAY.each do |holiday|
|
20
|
+
unless holiday[1] == 99
|
21
|
+
unless holiday[2] == 99 # 月日が既定のもの
|
22
|
+
jd_jst = gc2jd(year, holiday[1], holiday[2]) + Const::JST_D
|
23
|
+
yobi = compute_yobi(jd_jst)
|
24
|
+
holiday_0 << [holiday[1], holiday[2], holiday[0], jd_jst, yobi]
|
25
|
+
else # 月日が不定のもの
|
26
|
+
if holiday[3] == 21 # 第2月曜日 ( 8 - 14 の月曜日)
|
27
|
+
8.upto(14) do |d|
|
28
|
+
jd_jst = gc2jd(year, holiday[1], d) + Const::JST_D
|
29
|
+
yobi = compute_yobi(jd_jst)
|
30
|
+
holiday_0 << [holiday[1], d, holiday[0], jd_jst, "月"] if yobi == "月"
|
31
|
+
end
|
32
|
+
elsif holiday[3] == 31 # 第3月曜日 ( 15 - 21 の月曜日)
|
33
|
+
15.upto(21) do |d|
|
34
|
+
jd_jst = gc2jd(year, holiday[1], d) + Const::JST_D
|
35
|
+
yobi = compute_yobi(jd_jst)
|
36
|
+
holiday_0 << [holiday[1], d, holiday[0], jd_jst, "月"] if yobi == "月"
|
37
|
+
end
|
38
|
+
elsif holiday[3] == 80 # 春分の日
|
39
|
+
jd_jst = gc2jd(year, holiday[1], 31) + Const::JST_D
|
40
|
+
nibun_jd = compute_last_nc(jd_jst, 90)[0]
|
41
|
+
d = jd2ymd(nibun_jd)[2]
|
42
|
+
wk_jd = gc2jd(year, holiday[1], d) + Const::JST_D
|
43
|
+
yobi = compute_yobi(wk_jd)
|
44
|
+
holiday_0 << [holiday[1], d, holiday[0], wk_jd, yobi]
|
45
|
+
elsif holiday[3] == 81 # 秋分の日
|
46
|
+
jd_jst = gc2jd(year, holiday[1], 30) + Const::JST_D
|
47
|
+
nibun_jd = compute_last_nc(jd_jst, 90)[0]
|
48
|
+
d = jd2ymd(nibun_jd)[2]
|
49
|
+
wk_jd = gc2jd(year, holiday[1], d) + Const::JST_D
|
50
|
+
yobi = compute_yobi(wk_jd)
|
51
|
+
holiday_0 << [holiday[1], d, holiday[0], wk_jd, yobi]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# 国民の休日計算
|
58
|
+
# ( 「国民の祝日」で前後を挟まれた「国民の祝日」でない日 )
|
59
|
+
# ( 年またぎは考慮していない(今のところ不要) )
|
60
|
+
0.upto(holiday_0.length - 2) do |i|
|
61
|
+
if holiday_0[i][3] + 2 == holiday_0[i + 1][3]
|
62
|
+
jd = holiday_0[i][3] + 1
|
63
|
+
#yobi = (holiday_0[i][4] + 1) == 7 ? 0 : (holiday_0[i][4] + 1)
|
64
|
+
yobi = Const::YOBI[Const::YOBI.index(holiday_0[i][4]) + 1]
|
65
|
+
wk_ary = Array.new
|
66
|
+
wk_ary << jd2ymd(jd)[1]
|
67
|
+
wk_ary << jd2ymd(jd)[2]
|
68
|
+
wk_ary << 90
|
69
|
+
wk_ary << jd
|
70
|
+
wk_ary << yobi
|
71
|
+
holiday_1 << wk_ary
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# 振替休日計算
|
76
|
+
# ( 「国民の祝日」が日曜日に当たるときは、
|
77
|
+
# その日後においてその日に最も近い「国民の祝日」でない日 )
|
78
|
+
0.upto(holiday_0.length - 1) do |i|
|
79
|
+
if holiday_0[i][4] == 0
|
80
|
+
next_jd = holiday_0[i][3] + 1
|
81
|
+
#next_yobi = (holiday_0[i][4] + 1) == 7 ? 0 : (holiday_0[i][4] + 1)
|
82
|
+
next_yobi = Const::YOBI[Const::YOBI.index(holiday_0[i][4]) + 1]
|
83
|
+
if i == holiday_0.length - 1
|
84
|
+
wk_ary = Array.new
|
85
|
+
wk_ary << jd2ymd(next_jd)[1]
|
86
|
+
wk_ary << jd2ymd(next_jd)[2]
|
87
|
+
wk_ary << 91
|
88
|
+
wk_ary << next_jd
|
89
|
+
wk_ary << next_yobi
|
90
|
+
else
|
91
|
+
flg_furikae = 0
|
92
|
+
plus_day = 1
|
93
|
+
while flg_furikae == 0
|
94
|
+
if i + plus_day < holiday_0.length
|
95
|
+
if next_jd == holiday_0[i + plus_day][3]
|
96
|
+
next_jd += 1
|
97
|
+
next_yobi = (next_yobi + 1) == 7 ? 0 : (next_yobi + 1)
|
98
|
+
plus_day += 1
|
99
|
+
else
|
100
|
+
flg_furikae = 1
|
101
|
+
wk_ary = Array.new
|
102
|
+
wk_ary << jd2(next_jd)[1]
|
103
|
+
wk_ary << jd2(next_jd)[2]
|
104
|
+
wk_ary << 91
|
105
|
+
wk_ary << next_jd
|
106
|
+
wk_ary << next_yobi
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
holiday_2 << wk_ary
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# 配列整理
|
116
|
+
code = 99
|
117
|
+
(holiday_0 + holiday_1 + holiday_2).sort.each do |holiday|
|
118
|
+
if holiday[0] == month && holiday[1] == day
|
119
|
+
code = holiday[2]
|
120
|
+
break
|
121
|
+
end
|
122
|
+
end
|
123
|
+
holiday = ""
|
124
|
+
res = Const::HOLIDAY.select { |h| h[0] == code }
|
125
|
+
holiday = res[0][4] unless res == []
|
126
|
+
return holiday
|
127
|
+
end
|
128
|
+
|
129
|
+
#=========================================================================
|
130
|
+
# 二十四節気の計算
|
131
|
+
#
|
132
|
+
# @param: jd (ユリウス日(JST))
|
133
|
+
# @return: sekki_24 (二十四節気の文字列)
|
134
|
+
#=========================================================================
|
135
|
+
def compute_sekki_24(jd)
|
136
|
+
lsun_today = compute_lambda_sun(jd)
|
137
|
+
lsun_tomorrow = compute_lambda_sun(jd + 1)
|
138
|
+
lsun_today0 = 15 * (lsun_today / 15.0).truncate
|
139
|
+
lsun_tomorrow0 = 15 * (lsun_tomorrow / 15.0).truncate
|
140
|
+
return lsun_today0 == lsun_tomorrow0 ? "" : Const::SEKKI_24[lsun_tomorrow0 / 15]
|
141
|
+
end
|
142
|
+
|
143
|
+
#=========================================================================
|
144
|
+
# 雑節の計算
|
145
|
+
#
|
146
|
+
# @param: jd (ユリウス日(JST))
|
147
|
+
# @return: [雑節コード1, 雑節コード2]
|
148
|
+
#=========================================================================
|
149
|
+
def compute_zassetsu(jd)
|
150
|
+
zassetsu = Array.new
|
151
|
+
|
152
|
+
# 計算対象日の太陽の黄経
|
153
|
+
lsun_today = compute_lambda_sun(jd)
|
154
|
+
# 計算対象日の翌日の太陽の黄経
|
155
|
+
lsun_tomorrow = compute_lambda_sun(jd + 1)
|
156
|
+
# 計算対象日の5日前の太陽の黄経(社日計算用)
|
157
|
+
lsun_before_5 = compute_lambda_sun(jd - 5)
|
158
|
+
# 計算対象日の4日前の太陽の黄経(社日計算用)
|
159
|
+
lsun_before_4 = compute_lambda_sun(jd - 4)
|
160
|
+
# 計算対象日の5日後の太陽の黄経(社日計算用)
|
161
|
+
lsun_after_5 = compute_lambda_sun(jd + 5)
|
162
|
+
# 計算対象日の6日後の太陽の黄経(社日計算用)
|
163
|
+
lsun_after_6 = compute_lambda_sun(jd + 6)
|
164
|
+
# 太陽の黄経の整数部分( 土用, 入梅, 半夏生 計算用 )
|
165
|
+
lsun_today0 = lsun_today.truncate
|
166
|
+
lsun_tomorrow0 = lsun_tomorrow.truncate
|
167
|
+
|
168
|
+
#### ここから各種雑節計算
|
169
|
+
# 0:節分 ( 立春の前日 )
|
170
|
+
zassetsu << 0 if compute_sekki_24(jd + 1) == "立春"
|
171
|
+
# 1:彼岸入(春) ( 春分の日の3日前 )
|
172
|
+
zassetsu << 1 if compute_sekki_24(jd + 3) == "春分"
|
173
|
+
# 2:彼岸(春) ( 春分の日 )
|
174
|
+
zassetsu << 2 if compute_sekki_24(jd) == "春分"
|
175
|
+
# 3:彼岸明(春) ( 春分の日の3日後 )
|
176
|
+
zassetsu << 3 if compute_sekki_24(jd - 3) == "春分"
|
177
|
+
# 4:社日(春) ( 春分の日に最も近い戊(つちのえ)の日 )
|
178
|
+
# * 計算対象日が戊の日の時、
|
179
|
+
# * 4日後までもしくは4日前までに春分の日がある時、
|
180
|
+
# この日が社日
|
181
|
+
# * 5日後が春分の日の時、
|
182
|
+
# * 春分点(黄経0度)が午前なら
|
183
|
+
# この日が社日
|
184
|
+
# * 春分点(黄経0度)が午後なら
|
185
|
+
# この日の10日後が社日
|
186
|
+
if (jd % 10).truncate == 4 # 戊の日
|
187
|
+
# [ 当日から4日後 ]
|
188
|
+
0.upto(4) do |i|
|
189
|
+
if compute_sekki_24(jd + i) == "春分"
|
190
|
+
zassetsu << 4
|
191
|
+
break
|
192
|
+
end
|
193
|
+
end
|
194
|
+
# [ 1日前から4日前 ]
|
195
|
+
1.upto(4) do |i|
|
196
|
+
if compute_sekki_24(jd - i) == "春分"
|
197
|
+
zassetsu << 4
|
198
|
+
break
|
199
|
+
end
|
200
|
+
end
|
201
|
+
# [ 5日後 ]
|
202
|
+
if compute_sekki_24(jd + 5) == "春分"
|
203
|
+
# 春分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
|
204
|
+
# 0度(360度)以上なら、春分点が午前と判断
|
205
|
+
zassetsu << 4 if (lsun_after_5 + lsun_after_6 + 360) / 2.0 >= 360
|
206
|
+
end
|
207
|
+
# [ 5日前 ]
|
208
|
+
if compute_sekki_24(jd - 5) == "春分"
|
209
|
+
# 春分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
|
210
|
+
# 0度(360度)未満なら、春分点が午後と判断
|
211
|
+
zassetsu << 4 if (lsun_before_4 + lsun_before_5 + 360) / 2.0 < 360
|
212
|
+
end
|
213
|
+
end
|
214
|
+
# 5:土用入(春) ( 黄経(太陽) = 27度 )
|
215
|
+
unless lsun_today0 == lsun_tomorrow0
|
216
|
+
zassetsu << 5 if lsun_tomorrow0 == 27
|
217
|
+
end
|
218
|
+
# 6:八十八夜 ( 立春から88日目(87日後) )
|
219
|
+
zassetsu << 6 if compute_sekki_24(jd - 87) == "立春"
|
220
|
+
# 7:入梅 ( 黄経(太陽) = 80度 )
|
221
|
+
unless lsun_today0 == lsun_tomorrow0
|
222
|
+
zassetsu << 7 if lsun_tomorrow0 == 80
|
223
|
+
end
|
224
|
+
# 8:半夏生 ( 黄経(太陽) = 100度 )
|
225
|
+
unless lsun_today0 == lsun_tomorrow0
|
226
|
+
zassetsu << 8 if lsun_tomorrow0 == 100
|
227
|
+
end
|
228
|
+
# 9:土用入(夏) ( 黄経(太陽) = 117度 )
|
229
|
+
unless lsun_today0 == lsun_tomorrow0
|
230
|
+
zassetsu << 9 if lsun_tomorrow0 == 117
|
231
|
+
end
|
232
|
+
# 10:二百十日 ( 立春から210日目(209日後) )
|
233
|
+
zassetsu << 10 if compute_sekki_24(jd - 209) == "立春"
|
234
|
+
# 11:二百二十日 ( 立春から220日目(219日後) )
|
235
|
+
zassetsu << 11 if compute_sekki_24(jd - 219) == "立春"
|
236
|
+
# 12:彼岸入(秋) ( 秋分の日の3日前 )
|
237
|
+
zassetsu << 12 if compute_sekki_24(jd + 3) == "秋分"
|
238
|
+
# 13:彼岸(秋) ( 秋分の日 )
|
239
|
+
zassetsu << 13 if compute_sekki_24(jd) == "秋分"
|
240
|
+
# 14:彼岸明(秋) ( 秋分の日の3日後 )
|
241
|
+
zassetsu << 14 if compute_sekki_24(jd - 3) == "秋分"
|
242
|
+
# 15:社日(秋) ( 秋分の日に最も近い戊(つちのえ)の日 )
|
243
|
+
# * 計算対象日が戊の日の時、
|
244
|
+
# * 4日後までもしくは4日前までに秋分の日がある時、
|
245
|
+
# この日が社日
|
246
|
+
# * 5日後が秋分の日の時、
|
247
|
+
# * 秋分点(黄経180度)が午前なら
|
248
|
+
# この日が社日
|
249
|
+
# * 秋分点(黄経180度)が午後なら
|
250
|
+
# この日の10日後が社日
|
251
|
+
if (jd % 10).truncate == 4 # 戊の日
|
252
|
+
# [ 当日から4日後 ]
|
253
|
+
0.upto(4) do |i|
|
254
|
+
if compute_sekki_24(jd + i) == "秋分"
|
255
|
+
zassetsu << 15
|
256
|
+
break
|
257
|
+
end
|
258
|
+
end
|
259
|
+
# [ 1日前から4日前 ]
|
260
|
+
1.upto(4) do |i|
|
261
|
+
if compute_sekki_24(jd - i) == "秋分"
|
262
|
+
zassetsu << 15
|
263
|
+
break
|
264
|
+
end
|
265
|
+
end
|
266
|
+
# [ 5日後 ]
|
267
|
+
if compute_sekki_24(jd + 5) == "秋分"
|
268
|
+
# 秋分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
|
269
|
+
# 180度以上なら、秋分点が午前と判断
|
270
|
+
zassetsu << 15 if (lsun_after_5 + lsun_after_6) / 2.0 >= 180
|
271
|
+
end
|
272
|
+
# [ 5日前 ]
|
273
|
+
if compute_sekki_24(jd - 5) == "秋分"
|
274
|
+
# 秋分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
|
275
|
+
# 180度未満なら、秋分点が午後と判断
|
276
|
+
zassetsu << 15 if (lsun_before_4 + lsun_before_5) / 2.0 < 180
|
277
|
+
end
|
278
|
+
end
|
279
|
+
# 16:土用入(秋) ( 黄経(太陽) = 207度 )
|
280
|
+
unless lsun_today0 == lsun_tomorrow0
|
281
|
+
zassetsu << 16 if lsun_tomorrow0 == 207
|
282
|
+
end
|
283
|
+
# 17:土用入(冬) ( 黄経(太陽) = 297度 )
|
284
|
+
unless lsun_today0 == lsun_tomorrow0
|
285
|
+
zassetsu << 17 if lsun_tomorrow0 == 297
|
286
|
+
end
|
287
|
+
return zassetsu.map { |z| Const::ZASSETSU[z] }.join(",")
|
288
|
+
end
|
289
|
+
|
290
|
+
#=========================================================================
|
291
|
+
# 曜日の計算
|
292
|
+
#
|
293
|
+
# * 曜日 = ( ユリウス通日 + 2 ) % 7
|
294
|
+
# 0: 日曜, 1: 月曜, 2: 火曜, 3: 水曜, 4: 木曜, 5: 金曜, 6: 土曜
|
295
|
+
#
|
296
|
+
# @param: jd (ユリウス日(JST))
|
297
|
+
# @return: yobi (漢字1文字)
|
298
|
+
#=========================================================================
|
299
|
+
def compute_yobi(jd)
|
300
|
+
return Const::YOBI[(jd.to_i + 2) % 7]
|
301
|
+
end
|
302
|
+
|
303
|
+
#=========================================================================
|
304
|
+
# 干支の計算
|
305
|
+
#
|
306
|
+
# * [ユリウス日(JST) - 10日] を60で割った剰余
|
307
|
+
#
|
308
|
+
# @param: jd (ユリウス日(JST))
|
309
|
+
# @return kanshi (漢字2文字)
|
310
|
+
#=========================================================================
|
311
|
+
def compute_kanshi(jd)
|
312
|
+
return Const::KANSHI[(jd.to_i - 10) % 60]
|
313
|
+
end
|
314
|
+
|
315
|
+
#=========================================================================
|
316
|
+
# 節句の計算
|
317
|
+
#
|
318
|
+
# @param: month
|
319
|
+
# @param: day
|
320
|
+
# @return: sekku (日本語文字列)
|
321
|
+
#=========================================================================
|
322
|
+
def compute_sekku(month, day)
|
323
|
+
sekku = ""
|
324
|
+
res = Const::SEKKU.select { |s| s[1] == month && s[2] == day }
|
325
|
+
sekku = res[0][3] unless res == []
|
326
|
+
return sekku
|
327
|
+
end
|
328
|
+
|
329
|
+
#=========================================================================
|
330
|
+
# 太陽視黄経の計算
|
331
|
+
#
|
332
|
+
# @param: jd (ユリウス日(JST))
|
333
|
+
# @return: lambda
|
334
|
+
#=========================================================================
|
335
|
+
def compute_lambda_sun(jd)
|
336
|
+
year, month, day, hour, min, sec = jd2ymd(jd - 0.5)
|
337
|
+
t = (hour * 3600 + min * 60 + sec) / 86400.0
|
338
|
+
dt = compute_dt(year, month, day) # deltaT
|
339
|
+
dp = gc2j2000(year, month, day) # 2000年1月1日力学時正午からの経過日数(日)計算
|
340
|
+
jy = (t + dp + dt / 86400.0) / 365.25 # Julian Year
|
341
|
+
rm = 0.0003 * Math.sin(Const::K * norm_angle(329.7 + 44.43 * jy))
|
342
|
+
rm += 0.0003 * Math.sin(Const::K * norm_angle(352.5 + 1079.97 * jy))
|
343
|
+
rm += 0.0004 * Math.sin(Const::K * norm_angle( 21.1 + 720.02 * jy))
|
344
|
+
rm += 0.0004 * Math.sin(Const::K * norm_angle(157.3 + 299.30 * jy))
|
345
|
+
rm += 0.0004 * Math.sin(Const::K * norm_angle(234.9 + 315.56 * jy))
|
346
|
+
rm += 0.0005 * Math.sin(Const::K * norm_angle(291.2 + 22.81 * jy))
|
347
|
+
rm += 0.0005 * Math.sin(Const::K * norm_angle(207.4 + 1.50 * jy))
|
348
|
+
rm += 0.0006 * Math.sin(Const::K * norm_angle( 29.8 + 337.18 * jy))
|
349
|
+
rm += 0.0007 * Math.sin(Const::K * norm_angle(206.8 + 30.35 * jy))
|
350
|
+
rm += 0.0007 * Math.sin(Const::K * norm_angle(153.3 + 90.38 * jy))
|
351
|
+
rm += 0.0008 * Math.sin(Const::K * norm_angle(132.5 + 659.29 * jy))
|
352
|
+
rm += 0.0013 * Math.sin(Const::K * norm_angle( 81.4 + 225.18 * jy))
|
353
|
+
rm += 0.0015 * Math.sin(Const::K * norm_angle(343.2 + 450.37 * jy))
|
354
|
+
rm += 0.0018 * Math.sin(Const::K * norm_angle(251.3 + 0.20 * jy))
|
355
|
+
rm += 0.0018 * Math.sin(Const::K * norm_angle(297.8 + 4452.67 * jy))
|
356
|
+
rm += 0.0020 * Math.sin(Const::K * norm_angle(247.1 + 329.64 * jy))
|
357
|
+
rm += 0.0048 * Math.sin(Const::K * norm_angle(234.95 + 19.341 * jy))
|
358
|
+
rm += 0.0200 * Math.sin(Const::K * norm_angle(355.05 + 719.981 * jy))
|
359
|
+
rm += (1.9146 - 0.00005 * jy) * Math.sin(Const::K * norm_angle(357.538 + 359.991 * jy))
|
360
|
+
rm += norm_angle(280.4603 + 360.00769 * jy)
|
361
|
+
return norm_angle(rm)
|
362
|
+
end
|
363
|
+
|
364
|
+
#=========================================================================
|
365
|
+
# 月視黄経の計算
|
366
|
+
#
|
367
|
+
# @param: jd (ユリウス日(JST))
|
368
|
+
# @return: lambda
|
369
|
+
#=========================================================================
|
370
|
+
def compute_lambda_moon(jd)
|
371
|
+
year, month, day, hour, min, sec = jd2ymd(jd - 0.5)
|
372
|
+
t = (hour * 60 * 60 + min * 60 + sec) / 86400.0
|
373
|
+
dt = compute_dt(year, month, day) # deltaT
|
374
|
+
dp = gc2j2000(year, month, day) # 2000年1月1日力学時正午からの経過日数(日)計算
|
375
|
+
jy = (t + dp + dt / 86400.0) / 365.25 # Julian Year
|
376
|
+
am = 0.0006 * Math.sin(Const::K * norm_angle( 54.0 + 19.3 * jy))
|
377
|
+
am += 0.0006 * Math.sin(Const::K * norm_angle( 71.0 + 0.2 * jy))
|
378
|
+
am += 0.0020 * Math.sin(Const::K * norm_angle( 55.0 + 19.34 * jy))
|
379
|
+
am += 0.0040 * Math.sin(Const::K * norm_angle(119.5 + 1.33 * jy))
|
380
|
+
rm_moon = 0.0003 * Math.sin(Const::K * norm_angle(280.0 + 23221.3 * jy))
|
381
|
+
rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(161.0 + 40.7 * jy))
|
382
|
+
rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(311.0 + 5492.0 * jy))
|
383
|
+
rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(147.0 + 18089.3 * jy))
|
384
|
+
rm_moon += 0.0003 * Math.sin(Const::K * norm_angle( 66.0 + 3494.7 * jy))
|
385
|
+
rm_moon += 0.0003 * Math.sin(Const::K * norm_angle( 83.0 + 3814.0 * jy))
|
386
|
+
rm_moon += 0.0004 * Math.sin(Const::K * norm_angle( 20.0 + 720.0 * jy))
|
387
|
+
rm_moon += 0.0004 * Math.sin(Const::K * norm_angle( 71.0 + 9584.7 * jy))
|
388
|
+
rm_moon += 0.0004 * Math.sin(Const::K * norm_angle(278.0 + 120.1 * jy))
|
389
|
+
rm_moon += 0.0004 * Math.sin(Const::K * norm_angle(313.0 + 398.7 * jy))
|
390
|
+
rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(332.0 + 5091.3 * jy))
|
391
|
+
rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(114.0 + 17450.7 * jy))
|
392
|
+
rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(181.0 + 19088.0 * jy))
|
393
|
+
rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(247.0 + 22582.7 * jy))
|
394
|
+
rm_moon += 0.0006 * Math.sin(Const::K * norm_angle(128.0 + 1118.7 * jy))
|
395
|
+
rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(216.0 + 278.6 * jy))
|
396
|
+
rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(275.0 + 4853.3 * jy))
|
397
|
+
rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(140.0 + 4052.0 * jy))
|
398
|
+
rm_moon += 0.0008 * Math.sin(Const::K * norm_angle(204.0 + 7906.7 * jy))
|
399
|
+
rm_moon += 0.0008 * Math.sin(Const::K * norm_angle(188.0 + 14037.3 * jy))
|
400
|
+
rm_moon += 0.0009 * Math.sin(Const::K * norm_angle(218.0 + 8586.0 * jy))
|
401
|
+
rm_moon += 0.0011 * Math.sin(Const::K * norm_angle(276.5 + 19208.02 * jy))
|
402
|
+
rm_moon += 0.0012 * Math.sin(Const::K * norm_angle(339.0 + 12678.71 * jy))
|
403
|
+
rm_moon += 0.0016 * Math.sin(Const::K * norm_angle(242.2 + 18569.38 * jy))
|
404
|
+
rm_moon += 0.0018 * Math.sin(Const::K * norm_angle( 4.1 + 4013.29 * jy))
|
405
|
+
rm_moon += 0.0020 * Math.sin(Const::K * norm_angle( 55.0 + 19.34 * jy))
|
406
|
+
rm_moon += 0.0021 * Math.sin(Const::K * norm_angle(105.6 + 3413.37 * jy))
|
407
|
+
rm_moon += 0.0021 * Math.sin(Const::K * norm_angle(175.1 + 719.98 * jy))
|
408
|
+
rm_moon += 0.0021 * Math.sin(Const::K * norm_angle( 87.5 + 9903.97 * jy))
|
409
|
+
rm_moon += 0.0022 * Math.sin(Const::K * norm_angle(240.6 + 8185.36 * jy))
|
410
|
+
rm_moon += 0.0024 * Math.sin(Const::K * norm_angle(252.8 + 9224.66 * jy))
|
411
|
+
rm_moon += 0.0024 * Math.sin(Const::K * norm_angle(211.9 + 988.63 * jy))
|
412
|
+
rm_moon += 0.0026 * Math.sin(Const::K * norm_angle(107.2 + 13797.39 * jy))
|
413
|
+
rm_moon += 0.0027 * Math.sin(Const::K * norm_angle(272.5 + 9183.99 * jy))
|
414
|
+
rm_moon += 0.0037 * Math.sin(Const::K * norm_angle(349.1 + 5410.62 * jy))
|
415
|
+
rm_moon += 0.0039 * Math.sin(Const::K * norm_angle(111.3 + 17810.68 * jy))
|
416
|
+
rm_moon += 0.0040 * Math.sin(Const::K * norm_angle(119.5 + 1.33 * jy))
|
417
|
+
rm_moon += 0.0040 * Math.sin(Const::K * norm_angle(145.6 + 18449.32 * jy))
|
418
|
+
rm_moon += 0.0040 * Math.sin(Const::K * norm_angle( 13.2 + 13317.34 * jy))
|
419
|
+
rm_moon += 0.0048 * Math.sin(Const::K * norm_angle(235.0 + 19.34 * jy))
|
420
|
+
rm_moon += 0.0050 * Math.sin(Const::K * norm_angle(295.4 + 4812.66 * jy))
|
421
|
+
rm_moon += 0.0052 * Math.sin(Const::K * norm_angle(197.2 + 319.32 * jy))
|
422
|
+
rm_moon += 0.0068 * Math.sin(Const::K * norm_angle( 53.2 + 9265.33 * jy))
|
423
|
+
rm_moon += 0.0079 * Math.sin(Const::K * norm_angle(278.2 + 4493.34 * jy))
|
424
|
+
rm_moon += 0.0085 * Math.sin(Const::K * norm_angle(201.5 + 8266.71 * jy))
|
425
|
+
rm_moon += 0.0100 * Math.sin(Const::K * norm_angle( 44.89 + 14315.966 * jy))
|
426
|
+
rm_moon += 0.0107 * Math.sin(Const::K * norm_angle(336.44 + 13038.696 * jy))
|
427
|
+
rm_moon += 0.0110 * Math.sin(Const::K * norm_angle(231.59 + 4892.052 * jy))
|
428
|
+
rm_moon += 0.0125 * Math.sin(Const::K * norm_angle(141.51 + 14436.029 * jy))
|
429
|
+
rm_moon += 0.0153 * Math.sin(Const::K * norm_angle(130.84 + 758.698 * jy))
|
430
|
+
rm_moon += 0.0305 * Math.sin(Const::K * norm_angle(312.49 + 5131.979 * jy))
|
431
|
+
rm_moon += 0.0348 * Math.sin(Const::K * norm_angle(117.84 + 4452.671 * jy))
|
432
|
+
rm_moon += 0.0410 * Math.sin(Const::K * norm_angle(137.43 + 4411.998 * jy))
|
433
|
+
rm_moon += 0.0459 * Math.sin(Const::K * norm_angle(238.18 + 8545.352 * jy))
|
434
|
+
rm_moon += 0.0533 * Math.sin(Const::K * norm_angle( 10.66 + 13677.331 * jy))
|
435
|
+
rm_moon += 0.0572 * Math.sin(Const::K * norm_angle(103.21 + 3773.363 * jy))
|
436
|
+
rm_moon += 0.0588 * Math.sin(Const::K * norm_angle(214.22 + 638.635 * jy))
|
437
|
+
rm_moon += 0.1143 * Math.sin(Const::K * norm_angle( 6.546 + 9664.0404 * jy))
|
438
|
+
rm_moon += 0.1856 * Math.sin(Const::K * norm_angle(177.525 + 359.9905 * jy))
|
439
|
+
rm_moon += 0.2136 * Math.sin(Const::K * norm_angle(269.926 + 9543.9773 * jy))
|
440
|
+
rm_moon += 0.6583 * Math.sin(Const::K * norm_angle(235.700 + 8905.3422 * jy))
|
441
|
+
rm_moon += 1.2740 * Math.sin(Const::K * norm_angle(100.738 + 4133.3536 * jy))
|
442
|
+
rm_moon += 6.2887 * Math.sin(Const::K * norm_angle(134.961 + 4771.9886 * jy + am))
|
443
|
+
rm_moon += norm_angle(218.3161 + 4812.67881 * jy)
|
444
|
+
return norm_angle(rm_moon)
|
445
|
+
end
|
446
|
+
|
447
|
+
#=========================================================================
|
448
|
+
# 月齢(正午)の計算
|
449
|
+
#
|
450
|
+
# @param: jd (ユリウス日(JST))
|
451
|
+
# @return: moonage
|
452
|
+
#=========================================================================
|
453
|
+
def compute_moonage(jd)
|
454
|
+
return jd - compute_saku(jd)
|
455
|
+
end
|
456
|
+
|
457
|
+
#=========================================================================
|
458
|
+
# 旧暦の計算
|
459
|
+
#
|
460
|
+
# * 旧暦一日の六曜
|
461
|
+
# 1・7月 : 先勝
|
462
|
+
# 2・8月 : 友引
|
463
|
+
# 3・9月 : 先負
|
464
|
+
# 4・10月 : 仏滅
|
465
|
+
# 5・11月 : 大安
|
466
|
+
# 6・12月 : 赤口
|
467
|
+
# と決まっていて、あとは月末まで順番通り。
|
468
|
+
# よって、月と日をたした数を6で割った余りによって六曜を決定することができます。
|
469
|
+
# ( 旧暦の月 + 旧暦の日 ) ÷ 6 = ? … 余り
|
470
|
+
# 余り 0 : 大安
|
471
|
+
# 1 : 赤口
|
472
|
+
# 2 : 先勝
|
473
|
+
# 3 : 友引
|
474
|
+
# 4 : 先負
|
475
|
+
# 5 : 仏滅
|
476
|
+
#
|
477
|
+
# @param: jd (ユリウス日(JST))
|
478
|
+
# @return: [旧暦年, 閏月Flag, 旧暦月, 旧暦日, 六曜]
|
479
|
+
#=========================================================================
|
480
|
+
def compute_oc(jd)
|
481
|
+
jd -= 0.5
|
482
|
+
tm0 = jd
|
483
|
+
# 二分二至,中気の時刻・黄経用配列宣言
|
484
|
+
chu = Array.new(4).map { Array.new(2, 0) }
|
485
|
+
# 朔用配列宣言
|
486
|
+
saku = Array.new(5, 0)
|
487
|
+
# 朔日用配列宣言
|
488
|
+
m = Array.new(5).map { Array.new(3, 0) }
|
489
|
+
# 旧暦用配列宣言
|
490
|
+
kyureki = Array.new(4, 0)
|
491
|
+
|
492
|
+
# 計算対象の直前にあたる二分二至の時刻を計算
|
493
|
+
# chu[0][0] : 二分二至の時刻
|
494
|
+
# chu[0][1] : その時の太陽黄経
|
495
|
+
chu[0] = compute_last_nc(tm0, 90)
|
496
|
+
# 中気の時刻を計算 ( 3回計算する )
|
497
|
+
# chu[i][0] : 中気の時刻
|
498
|
+
# chu[i][1] : その時の太陽黄経
|
499
|
+
1.upto(3) do |i|
|
500
|
+
chu[i] = compute_last_nc(chu[i - 1][0] + 32, 30)
|
501
|
+
end
|
502
|
+
# 計算対象の直前にあたる二分二至の直前の朔の時刻を求める
|
503
|
+
saku[0] = compute_saku(chu[0][0])
|
504
|
+
# 朔の時刻を求める
|
505
|
+
1.upto(4) do |i|
|
506
|
+
tm = saku[i-1] + 30
|
507
|
+
saku[i] = compute_saku(tm)
|
508
|
+
# 前と同じ時刻を計算した場合( 両者の差が26日以内 )には、初期値を
|
509
|
+
# +33日にして再実行させる。
|
510
|
+
if (saku[i-1].truncate - saku[i].truncate).abs <= 26
|
511
|
+
saku[i] = compute_saku(saku[i-1] + 35)
|
512
|
+
end
|
513
|
+
end
|
514
|
+
# saku[1]が二分二至の時刻以前になってしまった場合には、朔をさかのぼり過ぎ
|
515
|
+
# たと考えて、朔の時刻を繰り下げて修正する。
|
516
|
+
# その際、計算もれ(saku[4])になっている部分を補うため、朔の時刻を計算
|
517
|
+
# する。(近日点通過の近辺で朔があると起こる事があるようだ...?)
|
518
|
+
if saku[1].truncate <= chu[0][0].truncate
|
519
|
+
0.upto(3) { |i| saku[i] = saku[i+1] }
|
520
|
+
saku[4] = compute_saku(saku[3] + 35)
|
521
|
+
# saku[0]が二分二至の時刻以後になってしまった場合には、朔をさかのぼり足
|
522
|
+
# りないと見て、朔の時刻を繰り上げて修正する。
|
523
|
+
# その際、計算もれ(saku[0])になっている部分を補うため、朔の時刻を計算
|
524
|
+
# する。(春分点の近辺で朔があると起こる事があるようだ...?)
|
525
|
+
elsif saku[0].truncate > chu[0][0].truncate
|
526
|
+
4.downto(1) { |i| saku[i] = saku[i-1] }
|
527
|
+
saku[0] = compute_saku(saku[0] - 27)
|
528
|
+
end
|
529
|
+
# 閏月検索Flagセット
|
530
|
+
# (節月で4ヶ月の間に朔が5回あると、閏月がある可能性がある。)
|
531
|
+
# leap=0:平月 leap=1:閏月
|
532
|
+
leap = 0
|
533
|
+
leap = 1 if saku[4].truncate <= chu[3][0].truncate
|
534
|
+
# 朔日行列の作成
|
535
|
+
# m[i][0] ... 月名 ( 1:正月 2:2月 3:3月 .... )
|
536
|
+
# m[i][1] ... 閏フラグ ( 0:平月 1:閏月 )
|
537
|
+
# m[i][2] ... 朔日のjd
|
538
|
+
m[0][0] = (chu[0][1] / 30.0).truncate + 2
|
539
|
+
m[0][0] -= 12 if m[0][0] > 12
|
540
|
+
m[0][2] = saku[0].truncate
|
541
|
+
m[0][1] = 0
|
542
|
+
1.upto(4) do |i|
|
543
|
+
if leap == 1 && i != 1
|
544
|
+
if chu[i-1][0].truncate <= saku[i-1].truncate ||
|
545
|
+
chu[i-1][0].truncate >= saku[i].truncate
|
546
|
+
m[i-1][0] = m[i-2][0]
|
547
|
+
m[i-1][1] = 1
|
548
|
+
m[i-1][2] = saku[i-1].truncate
|
549
|
+
leap = 0
|
550
|
+
end
|
551
|
+
end
|
552
|
+
m[i][0] = m[i-1][0] + 1
|
553
|
+
m[i][0] -= 12 if m[i][0] > 12
|
554
|
+
m[i][2] = saku[i].truncate
|
555
|
+
m[i][1] = 0
|
556
|
+
end
|
557
|
+
# 朔日行列から旧暦を求める。
|
558
|
+
state, index = 0, 0
|
559
|
+
0.upto(4) do |i|
|
560
|
+
index = i
|
561
|
+
if tm0.truncate < m[i][2].truncate
|
562
|
+
state = 1
|
563
|
+
break
|
564
|
+
elsif tm0.truncate == m[i][2].truncate
|
565
|
+
state = 2
|
566
|
+
break
|
567
|
+
end
|
568
|
+
end
|
569
|
+
index -= 1 if state == 1
|
570
|
+
kyureki[1] = m[index][1]
|
571
|
+
kyureki[2] = m[index][0]
|
572
|
+
kyureki[3] = tm0.truncate - m[index][2].truncate + 1
|
573
|
+
# 旧暦年の計算
|
574
|
+
# (旧暦月が10以上でかつ新暦月より大きい場合には、
|
575
|
+
# まだ年を越していないはず...)
|
576
|
+
a = jd2ymd(tm0)
|
577
|
+
kyureki[0] = a[0]
|
578
|
+
kyureki[0] -= 1 if kyureki[2] > 9 && kyureki[2] > a[1]
|
579
|
+
# 六曜
|
580
|
+
kyureki[4] = Const::ROKUYO[(kyureki[2] + kyureki[3]) % 6]
|
581
|
+
return kyureki
|
582
|
+
end
|
583
|
+
|
584
|
+
#=========================================================================
|
585
|
+
# Gregorian Calendar -> Julian Day
|
586
|
+
#
|
587
|
+
# * フリーゲルの公式を使用する
|
588
|
+
# [ JD ] = int( 365.25 × year )
|
589
|
+
# + int( year / 400 )
|
590
|
+
# - int( year / 100 )
|
591
|
+
# + int( 30.59 ( month - 2 ) )
|
592
|
+
# + day
|
593
|
+
# + 1721088
|
594
|
+
# ※上記の int( x ) は厳密には、x を超えない最大の整数
|
595
|
+
# ( ちなみに、[ 準JD ]を求めるなら + 1721088.5 が - 678912 となる )
|
596
|
+
#
|
597
|
+
# @param: year
|
598
|
+
# @param: month
|
599
|
+
# @param: day
|
600
|
+
# @param: hour
|
601
|
+
# @param: minute
|
602
|
+
# @param: second
|
603
|
+
# @return: jd ( ユリウス日 )
|
604
|
+
#=========================================================================
|
605
|
+
def gc2jd(year, month, day, hour = 0, min = 0, sec = 0)
|
606
|
+
# 1月,2月は前年の13月,14月とする
|
607
|
+
if month < 3
|
608
|
+
year -= 1
|
609
|
+
month += 12
|
610
|
+
end
|
611
|
+
# 日付(整数)部分計算
|
612
|
+
jd = (365.25 * year).truncate
|
613
|
+
jd += (year / 400.0).truncate
|
614
|
+
jd -= (year / 100.0).truncate
|
615
|
+
jd += (30.59 * (month - 2)).truncate
|
616
|
+
jd += day
|
617
|
+
jd += 1721088.125
|
618
|
+
# 時間(小数)部分計算
|
619
|
+
t = sec / 3600.0
|
620
|
+
t += min / 60.0
|
621
|
+
t += hour
|
622
|
+
t = t / 24.0
|
623
|
+
return jd + t
|
624
|
+
end
|
625
|
+
|
626
|
+
#=========================================================================
|
627
|
+
# Julian Day -> UT
|
628
|
+
#
|
629
|
+
# @param: jd (ユリウス日)
|
630
|
+
# @return: [year, month, day, hour, minute, second]
|
631
|
+
#=========================================================================
|
632
|
+
def jd2ymd(jd)
|
633
|
+
ut = Array.new(6, 0)
|
634
|
+
x0 = (jd + 68570).truncate
|
635
|
+
x1 = (x0 / 36524.25).truncate
|
636
|
+
x2 = x0 - (36524.25 * x1 + 0.75).truncate
|
637
|
+
x3 = ((x2 + 1) / 365.2425).truncate
|
638
|
+
x4 = x2 - (365.25 * x3).truncate + 31
|
639
|
+
x5 = (x4.truncate / 30.59).truncate
|
640
|
+
x6 = (x5.truncate / 11.0).truncate
|
641
|
+
ut[2] = x4 - (30.59 * x5).truncate
|
642
|
+
ut[1] = x5 - 12 * x6 + 2
|
643
|
+
ut[0] = 100 * (x1 - 49) + x3 + x6
|
644
|
+
# 2月30日の補正
|
645
|
+
if ut[1]==2 && ut[2] > 28
|
646
|
+
if ut[0] % 100 == 0 && ut[0] % 400 == 0
|
647
|
+
ut[2] = 29
|
648
|
+
elsif ut[0] % 4 == 0
|
649
|
+
ut[2] = 29
|
650
|
+
else
|
651
|
+
ut[2] = 28
|
652
|
+
end
|
653
|
+
end
|
654
|
+
tm = 86400 * (jd - jd.truncate)
|
655
|
+
ut[3] = (tm / 3600.0).truncate
|
656
|
+
ut[4] = ((tm - 3600 * ut[3]) / 60.0).truncate
|
657
|
+
ut[5] = (tm - 3600 * ut[3] - 60 * ut[4]).truncate
|
658
|
+
return ut
|
659
|
+
end
|
660
|
+
|
661
|
+
#=========================================================================
|
662
|
+
# 直前二分二至・中気時刻の計算
|
663
|
+
#
|
664
|
+
# @param: jd (ユリウス日)
|
665
|
+
# @param: kbn (90: 二分二至, 30: 中気)
|
666
|
+
# @return: [二分二至・中気の時刻, その時の黄経]
|
667
|
+
#=========================================================================
|
668
|
+
def compute_last_nc(jd, kbn)
|
669
|
+
jd -= 0.5
|
670
|
+
# 時刻引数を分解
|
671
|
+
tm1 = jd.truncate # 整数部分
|
672
|
+
tm2 = jd - tm1 # 小数部分
|
673
|
+
tm2 -= Const::JST_D
|
674
|
+
|
675
|
+
# 直前の二分二至の黄経 λsun0 を求める
|
676
|
+
rm_sun = compute_lambda_sun(jd + 0.5)
|
677
|
+
rm_sun0 = kbn * (rm_sun / kbn.to_f).truncate
|
678
|
+
|
679
|
+
# 繰り返し計算によって直前の二分二至の時刻を計算する
|
680
|
+
# (誤差が±1.0 sec以内になったら打ち切る。)
|
681
|
+
delta_t1 = 0 ; delta_t2 = 1
|
682
|
+
while (delta_t1 + delta_t2).abs > (1.0 / 86400.0)
|
683
|
+
# λsun を計算
|
684
|
+
t = tm1 + tm2 + Const::JST_D + 0.5
|
685
|
+
rm_sun = compute_lambda_sun(t)
|
686
|
+
|
687
|
+
# 黄経差 Δλ=λsun -λsun0
|
688
|
+
delta_rm = rm_sun - rm_sun0
|
689
|
+
|
690
|
+
# Δλの引き込み範囲(±180°)を逸脱した場合には、補正を行う
|
691
|
+
case
|
692
|
+
when delta_rm > 180; delta_rm -= 360
|
693
|
+
when delta_rm < -180; delta_rm += 360
|
694
|
+
end
|
695
|
+
|
696
|
+
# 時刻引数の補正値 Δt
|
697
|
+
delta_t1 = (delta_rm * 365.2 / 360.0).truncate
|
698
|
+
delta_t2 = delta_rm * 365.2 / 360.0 - delta_t1
|
699
|
+
|
700
|
+
# 時刻引数の補正
|
701
|
+
tm1 = tm1 - delta_t1
|
702
|
+
tm2 = tm2 - delta_t2
|
703
|
+
if tm2 < 0
|
704
|
+
tm2 += 1
|
705
|
+
tm1 -= 1
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
709
|
+
# nibun_chu[0] : 時刻引数を合成、DT ==> JST 変換を行い、戻り値とする
|
710
|
+
# ( 補正時刻=0.0sec と仮定して計算 )
|
711
|
+
# nibun_chu[1] : 黄経
|
712
|
+
nibun_chu = Array.new(2, 0)
|
713
|
+
nibun_chu[0] = tm2 + 9 / 24.0
|
714
|
+
nibun_chu[0] += tm1
|
715
|
+
nibun_chu[1] = rm_sun0
|
716
|
+
return nibun_chu
|
717
|
+
end
|
718
|
+
|
719
|
+
#=========================================================================
|
720
|
+
# 角度の正規化
|
721
|
+
#
|
722
|
+
# @param: angle
|
723
|
+
# @return: angle
|
724
|
+
#=========================================================================
|
725
|
+
def norm_angle(angle)
|
726
|
+
if angle < 0
|
727
|
+
angle1 = angle * (-1)
|
728
|
+
angle2 = (angle1 / 360.0).truncate
|
729
|
+
angle1 -= 360 * angle2
|
730
|
+
angle1 = 360 - angle1
|
731
|
+
else
|
732
|
+
angle1 = (angle / 360.0).truncate
|
733
|
+
angle1 = angle - 360.0 * angle1
|
734
|
+
end
|
735
|
+
return angle1
|
736
|
+
end
|
737
|
+
|
738
|
+
#=========================================================================
|
739
|
+
# 直近の朔の時刻(JST)の計算
|
740
|
+
#
|
741
|
+
# @param: jd (ユリウス日)
|
742
|
+
# @return: saku (直前の朔の時刻)
|
743
|
+
#=========================================================================
|
744
|
+
def compute_saku(jd)
|
745
|
+
jd -= 0.5
|
746
|
+
lc = 1
|
747
|
+
|
748
|
+
# 時刻引数を分解する
|
749
|
+
tm1 = jd.truncate
|
750
|
+
tm2 = jd - tm1
|
751
|
+
tm2 -= Const::JST_D
|
752
|
+
|
753
|
+
# 繰り返し計算によって朔の時刻を計算する
|
754
|
+
# (誤差が±1.0 sec以内になったら打ち切る。)
|
755
|
+
delta_t1 = 0 ; delta_t2 = 1
|
756
|
+
while (delta_t1 + delta_t2).abs > (1.0 / 86400.0)
|
757
|
+
# 太陽の黄経λsun ,月の黄経λmoon を計算
|
758
|
+
t = tm1 + tm2 + Const::JST_D + 0.5
|
759
|
+
rm_sun = compute_lambda_sun(t)
|
760
|
+
rm_moon = compute_lambda_moon(t)
|
761
|
+
# 月と太陽の黄経差Δλ
|
762
|
+
# Δλ=λmoon-λsun
|
763
|
+
delta_rm = rm_moon - rm_sun
|
764
|
+
# ループの1回目 ( lc = 1 ) で delta_rm < 0.0 の場合には引き込み範囲に
|
765
|
+
# 入るように補正する
|
766
|
+
if lc == 1 && delta_rm < 0
|
767
|
+
delta_rm = norm_angle(delta_rm)
|
768
|
+
# 春分の近くで朔がある場合 ( 0 ≦λsun≦ 20 ) で、月の黄経λmoon≧300 の
|
769
|
+
# 場合には、Δλ= 360.0 - Δλ と計算して補正する
|
770
|
+
elsif rm_sun >= 0 && rm_sun <= 20 && rm_moon >= 300
|
771
|
+
delta_rm = norm_angle(delta_rm)
|
772
|
+
delta_rm = 360 - delta_rm
|
773
|
+
# Δλの引き込み範囲 ( ±40° ) を逸脱した場合には、補正を行う
|
774
|
+
elsif delta_rm.abs > 40.0
|
775
|
+
delta_rm = norm_angle(delta_rm)
|
776
|
+
end
|
777
|
+
# 時刻引数の補正値 Δt
|
778
|
+
delta_t1 = (delta_rm * 29.530589 / 360.0).truncate
|
779
|
+
delta_t2 = delta_rm * 29.530589 / 360.0 - delta_t1
|
780
|
+
# 時刻引数の補正
|
781
|
+
tm1 = tm1 - delta_t1
|
782
|
+
tm2 = tm2 - delta_t2
|
783
|
+
if tm2 < 0
|
784
|
+
tm2 += 1
|
785
|
+
tm1 -= 1
|
786
|
+
end
|
787
|
+
# ループ回数が15回になったら、初期値 tm を tm-26 とする。
|
788
|
+
if lc == 15 && (delta_t1 + delta_t2).abs > (1.0 / 86400.0)
|
789
|
+
tm1 = (jd - 26).truncate
|
790
|
+
tm2 = 0
|
791
|
+
# 初期値を補正したにも関わらず、振動を続ける場合には初期値を答えとして
|
792
|
+
# 返して強制的にループを抜け出して異常終了させる。
|
793
|
+
elsif lc > 30 && (delta_t1+delta_t2).abs > (1.0 / 86400.0)
|
794
|
+
tm1 = jd
|
795
|
+
tm2 = 0
|
796
|
+
break
|
797
|
+
end
|
798
|
+
lc += 1
|
799
|
+
end
|
800
|
+
# 時刻引数を合成、DT ==> JST 変換を行い、戻り値とする
|
801
|
+
# (補正時刻=0.0sec と仮定して計算)
|
802
|
+
return tm2 + tm1 + 9 / 24.0
|
803
|
+
end
|
804
|
+
|
805
|
+
#=========================================================================
|
806
|
+
# ΔT の計算
|
807
|
+
#
|
808
|
+
# * 1972-01-01 以降、うるう秒挿入済みの年+αまでは、以下で算出
|
809
|
+
# TT - UTC = ΔT + DUT1 = TAI + 32.184 - UTC = ΔAT + 32.184
|
810
|
+
# [うるう秒実施日一覧](http://jjy.nict.go.jp/QandA/data/leapsec.html)
|
811
|
+
#
|
812
|
+
# @param: year
|
813
|
+
# @param: month
|
814
|
+
# @param: day
|
815
|
+
# @return: dt
|
816
|
+
#=========================================================================
|
817
|
+
def compute_dt(year, month, day)
|
818
|
+
ymd = sprintf("%04d-%02d-%02d", year, month, day)
|
819
|
+
case
|
820
|
+
when year < -500
|
821
|
+
t = (year-1820) / 100.0
|
822
|
+
dt = -20 + 32 * t ** 2
|
823
|
+
when -500 <= year && year < 500
|
824
|
+
t = year / 100.0
|
825
|
+
dt = 10583.6
|
826
|
+
(-1014.41 + \
|
827
|
+
( 33.78311 + \
|
828
|
+
( -5.952053 + \
|
829
|
+
( -0.1798452 + \
|
830
|
+
( 0.022174192 + \
|
831
|
+
( 0.0090316521) \
|
832
|
+
* t) * t) * t) * t) * t) * t
|
833
|
+
when 500 <= year && year < 1600
|
834
|
+
t = (year - 1000) / 100.0
|
835
|
+
dt = 1574.2 + \
|
836
|
+
(-556.01 + \
|
837
|
+
( 71.23472 + \
|
838
|
+
( 0.319781 + \
|
839
|
+
( -0.8503463 + \
|
840
|
+
( -0.005050998 + \
|
841
|
+
( 0.0083572073) \
|
842
|
+
* t) * t) * t) * t) * t) * t
|
843
|
+
when 1600 <= year && year < 1700
|
844
|
+
t = year - 1600
|
845
|
+
dt = 120 + \
|
846
|
+
( -0.9808 + \
|
847
|
+
( -0.01532 + \
|
848
|
+
( 1.0 / 7129.0) \
|
849
|
+
* t) * t) * t
|
850
|
+
when 1700 <= year && year < 1800
|
851
|
+
t = year - 1700
|
852
|
+
dt = 8.83 + \
|
853
|
+
( 0.1603 + \
|
854
|
+
(-0.0059285 + \
|
855
|
+
( 0.00013336 + \
|
856
|
+
(-1.0 / 1174000.0) \
|
857
|
+
* t) * t) * t) * t
|
858
|
+
when 1800 <= year && year < 1860
|
859
|
+
t = year - 1800
|
860
|
+
dt = 13.72 + \
|
861
|
+
(-0.332447 + \
|
862
|
+
( 0.0068612 + \
|
863
|
+
( 0.0041116 + \
|
864
|
+
(-0.00037436 + \
|
865
|
+
( 0.0000121272 + \
|
866
|
+
(-0.0000001699 + \
|
867
|
+
( 0.000000000875) \
|
868
|
+
* t) * t) * t) * t) * t) * t) * t
|
869
|
+
when 1860 <= year && year < 1900
|
870
|
+
t = year - 1860
|
871
|
+
dt = 7.62 + \
|
872
|
+
( 0.5737 + \
|
873
|
+
(-0.251754 + \
|
874
|
+
( 0.01680668 + \
|
875
|
+
(-0.0004473624 + \
|
876
|
+
( 1.0 / 233174.0) \
|
877
|
+
* t) * t) * t) * t) * t
|
878
|
+
when 1900 <= year && year < 1920
|
879
|
+
t = year - 1900
|
880
|
+
dt = -2.79 + \
|
881
|
+
( 1.494119 + \
|
882
|
+
(-0.0598939 + \
|
883
|
+
( 0.0061966 + \
|
884
|
+
(-0.000197 ) \
|
885
|
+
* t) * t) * t) * t
|
886
|
+
when 1920 <= year && year < 1941
|
887
|
+
t = year - 1920
|
888
|
+
dt = 21.20 + \
|
889
|
+
( 0.84493 + \
|
890
|
+
(-0.076100 + \
|
891
|
+
( 0.0020936) \
|
892
|
+
* t) * t) * t
|
893
|
+
when 1941 <= year && year < 1961
|
894
|
+
t = year - 1950
|
895
|
+
dt = 29.07 + \
|
896
|
+
( 0.407 + \
|
897
|
+
(-1 / 233.0 + \
|
898
|
+
( 1 / 2547.0) \
|
899
|
+
* t) * t) * t
|
900
|
+
when 1961 <= year && year < 1986
|
901
|
+
case
|
902
|
+
when ymd < sprintf("%04d-%02d-%02d", 1972, 1, 1)
|
903
|
+
t = year - 1975
|
904
|
+
dt = 45.45 + \
|
905
|
+
( 1.067 + \
|
906
|
+
(-1 / 260.0 + \
|
907
|
+
(-1 / 718.0) \
|
908
|
+
* t) * t) * t
|
909
|
+
when ymd < sprintf("%04d-%02d-%02d", 1972, 7, 1)
|
910
|
+
dt = 32.184 + 10
|
911
|
+
when ymd < sprintf("%04d-%02d-%02d", 1973, 1, 1)
|
912
|
+
dt = 32.184 + 11
|
913
|
+
when ymd < sprintf("%04d-%02d-%02d", 1974, 1, 1)
|
914
|
+
dt = 32.184 + 12
|
915
|
+
when ymd < sprintf("%04d-%02d-%02d", 1975, 1, 1)
|
916
|
+
dt = 32.184 + 13
|
917
|
+
when ymd < sprintf("%04d-%02d-%02d", 1976, 1, 1)
|
918
|
+
dt = 32.184 + 14
|
919
|
+
when ymd < sprintf("%04d-%02d-%02d", 1977, 1, 1)
|
920
|
+
dt = 32.184 + 15
|
921
|
+
when ymd < sprintf("%04d-%02d-%02d", 1978, 1, 1)
|
922
|
+
dt = 32.184 + 16
|
923
|
+
when ymd < sprintf("%04d-%02d-%02d", 1979, 1, 1)
|
924
|
+
dt = 32.184 + 17
|
925
|
+
when ymd < sprintf("%04d-%02d-%02d", 1980, 1, 1)
|
926
|
+
dt = 32.184 + 18
|
927
|
+
when ymd < sprintf("%04d-%02d-%02d", 1981, 7, 1)
|
928
|
+
dt = 32.184 + 19
|
929
|
+
when ymd < sprintf("%04d-%02d-%02d", 1982, 7, 1)
|
930
|
+
dt = 32.184 + 20
|
931
|
+
when ymd < sprintf("%04d-%02d-%02d", 1983, 7, 1)
|
932
|
+
dt = 32.184 + 21
|
933
|
+
when ymd < sprintf("%04d-%02d-%02d", 1985, 7, 1)
|
934
|
+
dt = 32.184 + 22
|
935
|
+
when ymd < sprintf("%04d-%02d-%02d", 1988, 1, 1)
|
936
|
+
dt = 32.184 + 23
|
937
|
+
end
|
938
|
+
when 1986 <= year && year < 2005
|
939
|
+
# t = year - 2000
|
940
|
+
#dt = 63.86 + \
|
941
|
+
# ( 0.3345 + \
|
942
|
+
# (-0.060374 + \
|
943
|
+
# ( 0.0017275 + \
|
944
|
+
# ( 0.000651814 + \
|
945
|
+
# ( 0.00002373599) \
|
946
|
+
# * t) * t) * t) * t) * t
|
947
|
+
case
|
948
|
+
when ymd < sprintf("%04d-%02d-%02d", 1988, 1, 1)
|
949
|
+
dt = 32.184 + 23
|
950
|
+
when ymd < sprintf("%04d-%02d-%02d", 1990, 1, 1)
|
951
|
+
dt = 32.184 + 24
|
952
|
+
when ymd < sprintf("%04d-%02d-%02d", 1991, 1, 1)
|
953
|
+
dt = 32.184 + 25
|
954
|
+
when ymd < sprintf("%04d-%02d-%02d", 1992, 7, 1)
|
955
|
+
dt = 32.184 + 26
|
956
|
+
when ymd < sprintf("%04d-%02d-%02d", 1993, 7, 1)
|
957
|
+
dt = 32.184 + 27
|
958
|
+
when ymd < sprintf("%04d-%02d-%02d", 1994, 7, 1)
|
959
|
+
dt = 32.184 + 28
|
960
|
+
when ymd < sprintf("%04d-%02d-%02d", 1996, 1, 1)
|
961
|
+
dt = 32.184 + 29
|
962
|
+
when ymd < sprintf("%04d-%02d-%02d", 1997, 7, 1)
|
963
|
+
dt = 32.184 + 30
|
964
|
+
when ymd < sprintf("%04d-%02d-%02d", 1999, 1, 1)
|
965
|
+
dt = 32.184 + 31
|
966
|
+
when ymd < sprintf("%04d-%02d-%02d", 2006, 1, 1)
|
967
|
+
dt = 32.184 + 32
|
968
|
+
end
|
969
|
+
when 2005 <= year && year < 2050
|
970
|
+
case
|
971
|
+
when ymd < sprintf("%04d-%02d-%02d", 2006, 1, 1)
|
972
|
+
dt = 32.184 + 32
|
973
|
+
when ymd < sprintf("%04d-%02d-%02d", 2009, 1, 1)
|
974
|
+
dt = 32.184 + 33
|
975
|
+
when ymd < sprintf("%04d-%02d-%02d", 2012, 7, 1)
|
976
|
+
dt = 32.184 + 34
|
977
|
+
when ymd < sprintf("%04d-%02d-%02d", 2015, 7, 1)
|
978
|
+
dt = 32.184 + 35
|
979
|
+
when ymd < sprintf("%04d-%02d-%02d", 2017, 7, 1) # <= 第27回うるう秒実施までの暫定措置
|
980
|
+
dt = 32.184 + 36
|
981
|
+
else
|
982
|
+
t = year - 2000
|
983
|
+
dt = 62.92 + \
|
984
|
+
( 0.32217 + \
|
985
|
+
( 0.005589) \
|
986
|
+
* t) * t
|
987
|
+
end
|
988
|
+
when 2050 <= year && year <= 2150
|
989
|
+
dt = -20 \
|
990
|
+
+ 32 * ((year - 1820) / 100.0) ** 2
|
991
|
+
- 0.5628 * (2150 - year)
|
992
|
+
when 2150 < year
|
993
|
+
t = (year - 1820) / 100.0
|
994
|
+
dt = -20 + 32 * t ** 2
|
995
|
+
end
|
996
|
+
return dt
|
997
|
+
end
|
998
|
+
|
999
|
+
#=========================================================================
|
1000
|
+
# 2000年1月1日力学時正午からの経過日数の計算
|
1001
|
+
#
|
1002
|
+
# @param: year
|
1003
|
+
# @param: month
|
1004
|
+
# @param: day
|
1005
|
+
# @return: dp (= day progress)
|
1006
|
+
#=========================================================================
|
1007
|
+
def gc2j2000(year, month, day)
|
1008
|
+
year -= 2000
|
1009
|
+
# 1月,2月は前年の13月,14月とする
|
1010
|
+
if month < 3
|
1011
|
+
year -= 1
|
1012
|
+
month += 12
|
1013
|
+
end
|
1014
|
+
dp = 365 * year + 30 * month + day - 33.5 - Const::JST_D
|
1015
|
+
dp += (3 * (month + 1) / 5.0).truncate
|
1016
|
+
dp += (year / 4.0).truncate
|
1017
|
+
return dp
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
#=========================================================================
|
1021
|
+
# 六曜の計算
|
1022
|
+
#
|
1023
|
+
#
|
1024
|
+
# @param: oc_month (旧暦の月)
|
1025
|
+
# @param: oc_day (旧暦の日)
|
1026
|
+
# @return: rokuyo (漢字2文字)
|
1027
|
+
#=========================================================================
|
1028
|
+
def compute_rokuyo(oc_month, oc_day)
|
1029
|
+
return Const::ROKUYO[(oc_month + oc_day) % 6]
|
1030
|
+
end
|
1031
|
+
end
|
1032
|
+
end
|
1033
|
+
|