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.
@@ -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
+