mk_calendar 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+