module MkCalendar::Compute
Public Instance Methods
compute_alpha(jd)
click to toggle source
¶ ↑
月視黄経の計算 @param: jd (ユリウス日(JST)) @return: lambda
¶ ↑
# File lib/mk_calendar/compute.rb, line 368 def compute_alpha(jd) year, month, day, hour, min, sec = jd2ymd(jd - Const::JST_D) dt = compute_dt(year, month, day) # deltaT jy = (jd - Const::JST_D + dt / 86400.0 - 2451545.0) / 365.25 # Julian Year am = 0.0006 * Math.sin(Const::K * norm_angle( 54.0 + 19.3 * jy)) am += 0.0006 * Math.sin(Const::K * norm_angle( 71.0 + 0.2 * jy)) am += 0.0020 * Math.sin(Const::K * norm_angle( 55.0 + 19.34 * jy)) am += 0.0040 * Math.sin(Const::K * norm_angle(119.5 + 1.33 * jy)) rm_moon = 0.0003 * Math.sin(Const::K * norm_angle(280.0 + 23221.3 * jy)) rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(161.0 + 40.7 * jy)) rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(311.0 + 5492.0 * jy)) rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(147.0 + 18089.3 * jy)) rm_moon += 0.0003 * Math.sin(Const::K * norm_angle( 66.0 + 3494.7 * jy)) rm_moon += 0.0003 * Math.sin(Const::K * norm_angle( 83.0 + 3814.0 * jy)) rm_moon += 0.0004 * Math.sin(Const::K * norm_angle( 20.0 + 720.0 * jy)) rm_moon += 0.0004 * Math.sin(Const::K * norm_angle( 71.0 + 9584.7 * jy)) rm_moon += 0.0004 * Math.sin(Const::K * norm_angle(278.0 + 120.1 * jy)) rm_moon += 0.0004 * Math.sin(Const::K * norm_angle(313.0 + 398.7 * jy)) rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(332.0 + 5091.3 * jy)) rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(114.0 + 17450.7 * jy)) rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(181.0 + 19088.0 * jy)) rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(247.0 + 22582.7 * jy)) rm_moon += 0.0006 * Math.sin(Const::K * norm_angle(128.0 + 1118.7 * jy)) rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(216.0 + 278.6 * jy)) rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(275.0 + 4853.3 * jy)) rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(140.0 + 4052.0 * jy)) rm_moon += 0.0008 * Math.sin(Const::K * norm_angle(204.0 + 7906.7 * jy)) rm_moon += 0.0008 * Math.sin(Const::K * norm_angle(188.0 + 14037.3 * jy)) rm_moon += 0.0009 * Math.sin(Const::K * norm_angle(218.0 + 8586.0 * jy)) rm_moon += 0.0011 * Math.sin(Const::K * norm_angle(276.5 + 19208.02 * jy)) rm_moon += 0.0012 * Math.sin(Const::K * norm_angle(339.0 + 12678.71 * jy)) rm_moon += 0.0016 * Math.sin(Const::K * norm_angle(242.2 + 18569.38 * jy)) rm_moon += 0.0018 * Math.sin(Const::K * norm_angle( 4.1 + 4013.29 * jy)) rm_moon += 0.0020 * Math.sin(Const::K * norm_angle( 55.0 + 19.34 * jy)) rm_moon += 0.0021 * Math.sin(Const::K * norm_angle(105.6 + 3413.37 * jy)) rm_moon += 0.0021 * Math.sin(Const::K * norm_angle(175.1 + 719.98 * jy)) rm_moon += 0.0021 * Math.sin(Const::K * norm_angle( 87.5 + 9903.97 * jy)) rm_moon += 0.0022 * Math.sin(Const::K * norm_angle(240.6 + 8185.36 * jy)) rm_moon += 0.0024 * Math.sin(Const::K * norm_angle(252.8 + 9224.66 * jy)) rm_moon += 0.0024 * Math.sin(Const::K * norm_angle(211.9 + 988.63 * jy)) rm_moon += 0.0026 * Math.sin(Const::K * norm_angle(107.2 + 13797.39 * jy)) rm_moon += 0.0027 * Math.sin(Const::K * norm_angle(272.5 + 9183.99 * jy)) rm_moon += 0.0037 * Math.sin(Const::K * norm_angle(349.1 + 5410.62 * jy)) rm_moon += 0.0039 * Math.sin(Const::K * norm_angle(111.3 + 17810.68 * jy)) rm_moon += 0.0040 * Math.sin(Const::K * norm_angle(119.5 + 1.33 * jy)) rm_moon += 0.0040 * Math.sin(Const::K * norm_angle(145.6 + 18449.32 * jy)) rm_moon += 0.0040 * Math.sin(Const::K * norm_angle( 13.2 + 13317.34 * jy)) rm_moon += 0.0048 * Math.sin(Const::K * norm_angle(235.0 + 19.34 * jy)) rm_moon += 0.0050 * Math.sin(Const::K * norm_angle(295.4 + 4812.66 * jy)) rm_moon += 0.0052 * Math.sin(Const::K * norm_angle(197.2 + 319.32 * jy)) rm_moon += 0.0068 * Math.sin(Const::K * norm_angle( 53.2 + 9265.33 * jy)) rm_moon += 0.0079 * Math.sin(Const::K * norm_angle(278.2 + 4493.34 * jy)) rm_moon += 0.0085 * Math.sin(Const::K * norm_angle(201.5 + 8266.71 * jy)) rm_moon += 0.0100 * Math.sin(Const::K * norm_angle( 44.89 + 14315.966 * jy)) rm_moon += 0.0107 * Math.sin(Const::K * norm_angle(336.44 + 13038.696 * jy)) rm_moon += 0.0110 * Math.sin(Const::K * norm_angle(231.59 + 4892.052 * jy)) rm_moon += 0.0125 * Math.sin(Const::K * norm_angle(141.51 + 14436.029 * jy)) rm_moon += 0.0153 * Math.sin(Const::K * norm_angle(130.84 + 758.698 * jy)) rm_moon += 0.0305 * Math.sin(Const::K * norm_angle(312.49 + 5131.979 * jy)) rm_moon += 0.0348 * Math.sin(Const::K * norm_angle(117.84 + 4452.671 * jy)) rm_moon += 0.0410 * Math.sin(Const::K * norm_angle(137.43 + 4411.998 * jy)) rm_moon += 0.0459 * Math.sin(Const::K * norm_angle(238.18 + 8545.352 * jy)) rm_moon += 0.0533 * Math.sin(Const::K * norm_angle( 10.66 + 13677.331 * jy)) rm_moon += 0.0572 * Math.sin(Const::K * norm_angle(103.21 + 3773.363 * jy)) rm_moon += 0.0588 * Math.sin(Const::K * norm_angle(214.22 + 638.635 * jy)) rm_moon += 0.1143 * Math.sin(Const::K * norm_angle( 6.546 + 9664.0404 * jy)) rm_moon += 0.1856 * Math.sin(Const::K * norm_angle(177.525 + 359.9905 * jy)) rm_moon += 0.2136 * Math.sin(Const::K * norm_angle(269.926 + 9543.9773 * jy)) rm_moon += 0.6583 * Math.sin(Const::K * norm_angle(235.700 + 8905.3422 * jy)) rm_moon += 1.2740 * Math.sin(Const::K * norm_angle(100.738 + 4133.3536 * jy)) rm_moon += 6.2887 * Math.sin(Const::K * norm_angle(134.961 + 4771.9886 * jy + am)) rm_moon += norm_angle(218.3161 + 4812.67881 * jy) return norm_angle(rm_moon) end
compute_dt(year, month, day)
click to toggle source
¶ ↑
ΔT の計算 * 1972-01-01 以降、うるう秒挿入済みの年+αまでは、以下で算出 TT - UTC = ΔT + DUT1 = TAI + 32.184 - UTC = ΔAT + 32.184 [うるう秒実施日一覧](http://jjy.nict.go.jp/QandA/data/leapsec.html) @param: year @param: month @param: day @return: dt
¶ ↑
# File lib/mk_calendar/compute.rb, line 812 def compute_dt(year, month, day) ymd = sprintf("%04d%02d%02d", year, month, day) tm = MkTime.new(ymd) return tm.dt end
compute_holiday(year, month, day)
click to toggle source
¶ ↑
休日の計算 @param: year @param: month @param: day @return: holiday (漢字1文字)
¶ ↑
# File lib/mk_calendar/compute.rb, line 15 def compute_holiday(year, month, day) holiday_0 = Array.new # 変動の祝日用 holiday_1 = Array.new # 国民の休日用 holiday_2 = Array.new # 振替休日用 # 変動の祝日の日付・曜日を計算 ( 振替休日,国民の休日を除く ) Const::HOLIDAY.each do |holiday| unless holiday[1] == 99 unless holiday[2] == 99 # 月日が既定のもの jd_jst = gc2jd(year, holiday[1], holiday[2]) + Const::JST_D yobi = compute_yobi(jd_jst) holiday_0 << [holiday[1], holiday[2], holiday[0], jd_jst, yobi] else # 月日が不定のもの if holiday[3] == 21 # 第2月曜日 ( 8 - 14 の月曜日) 8.upto(14) do |d| jd_jst = gc2jd(year, holiday[1], d) + Const::JST_D yobi = compute_yobi(jd_jst) holiday_0 << [holiday[1], d, holiday[0], jd_jst, "月"] if yobi == "月" end elsif holiday[3] == 31 # 第3月曜日 ( 15 - 21 の月曜日) 15.upto(21) do |d| jd_jst = gc2jd(year, holiday[1], d) + Const::JST_D yobi = compute_yobi(jd_jst) holiday_0 << [holiday[1], d, holiday[0], jd_jst, "月"] if yobi == "月" end elsif holiday[3] == 80 # 春分の日 jd_jst = gc2jd(year, holiday[1], 31) + Const::JST_D nibun_jd = compute_last_nc(jd_jst, 90)[0] d = jd2ymd(nibun_jd)[2] wk_jd = gc2jd(year, holiday[1], d) + Const::JST_D yobi = compute_yobi(wk_jd) holiday_0 << [holiday[1], d, holiday[0], wk_jd, yobi] elsif holiday[3] == 81 # 秋分の日 jd_jst = gc2jd(year, holiday[1], 30) + Const::JST_D nibun_jd = compute_last_nc(jd_jst, 90)[0] d = jd2ymd(nibun_jd)[2] wk_jd = gc2jd(year, holiday[1], d) + Const::JST_D yobi = compute_yobi(wk_jd) holiday_0 << [holiday[1], d, holiday[0], wk_jd, yobi] end end end end # 国民の休日計算 # ( 「国民の祝日」で前後を挟まれた「国民の祝日」でない日 ) # ( 年またぎは考慮していない(今のところ不要) ) 0.upto(holiday_0.length - 2) do |i| if holiday_0[i][3] + 2 == holiday_0[i + 1][3] jd = holiday_0[i][3] + 1 yobi = Const::YOBI[Const::YOBI.index(holiday_0[i][4]) + 1] wk_ary = Array.new wk_ary << jd2ymd(jd)[1] wk_ary << jd2ymd(jd)[2] wk_ary << 90 wk_ary << jd wk_ary << yobi holiday_1 << wk_ary end end # 振替休日計算 # ( 「国民の祝日」が日曜日に当たるときは、 # その日後においてその日に最も近い「国民の祝日」でない日 ) 0.upto(holiday_0.length - 1) do |i| if holiday_0[i][4] == "日" next_jd = holiday_0[i][3] + 1 next_yobi = Const::YOBI[Const::YOBI.index(holiday_0[i][4]) + 1] if i == holiday_0.length - 1 wk_ary = Array.new wk_ary << jd2ymd(next_jd)[1] wk_ary << jd2ymd(next_jd)[2] wk_ary << 91 wk_ary << next_jd wk_ary << next_yobi else flg_furikae = 0 plus_day = 1 while flg_furikae == 0 if i + plus_day < holiday_0.length if next_jd == holiday_0[i + plus_day][3] next_jd += 1 next_yobi = next_yobi == "土" ? "日" : Const::YOBI[Const::YOBI.index(next_yobi) + 1] plus_day += 1 else flg_furikae = 1 wk_ary = Array.new wk_ary << jd2ymd(next_jd)[1] wk_ary << jd2ymd(next_jd)[2] wk_ary << 91 wk_ary << next_jd wk_ary << next_yobi end end end end holiday_2 << wk_ary end end # 配列整理 code = 99 (holiday_0 + holiday_1 + holiday_2).sort.each do |holiday| if holiday[0] == month && holiday[1] == day code = holiday[2] break end end holiday = "" res = Const::HOLIDAY.select { |h| h[0] == code } holiday = res[0][4] unless res == [] return holiday end
compute_kanshi(jd)
click to toggle source
compute_lambda(jd)
click to toggle source
¶ ↑
太陽視黄経の計算 @param: jd (ユリウス日(JST)) @return: lambda
¶ ↑
# File lib/mk_calendar/compute.rb, line 335 def compute_lambda(jd) year, month, day, hour, min, sec = jd2ymd(jd - Const::JST_D) dt = compute_dt(year, month, day) # deltaT jy = (jd - Const::JST_D + dt / 86400.0 - 2451545.0) / 365.25 # Julian Year rm = 0.0003 * Math.sin(Const::K * norm_angle(329.7 + 44.43 * jy)) rm += 0.0003 * Math.sin(Const::K * norm_angle(352.5 + 1079.97 * jy)) rm += 0.0004 * Math.sin(Const::K * norm_angle( 21.1 + 720.02 * jy)) rm += 0.0004 * Math.sin(Const::K * norm_angle(157.3 + 299.30 * jy)) rm += 0.0004 * Math.sin(Const::K * norm_angle(234.9 + 315.56 * jy)) rm += 0.0005 * Math.sin(Const::K * norm_angle(291.2 + 22.81 * jy)) rm += 0.0005 * Math.sin(Const::K * norm_angle(207.4 + 1.50 * jy)) rm += 0.0006 * Math.sin(Const::K * norm_angle( 29.8 + 337.18 * jy)) rm += 0.0007 * Math.sin(Const::K * norm_angle(206.8 + 30.35 * jy)) rm += 0.0007 * Math.sin(Const::K * norm_angle(153.3 + 90.38 * jy)) rm += 0.0008 * Math.sin(Const::K * norm_angle(132.5 + 659.29 * jy)) rm += 0.0013 * Math.sin(Const::K * norm_angle( 81.4 + 225.18 * jy)) rm += 0.0015 * Math.sin(Const::K * norm_angle(343.2 + 450.37 * jy)) rm += 0.0018 * Math.sin(Const::K * norm_angle(251.3 + 0.20 * jy)) rm += 0.0018 * Math.sin(Const::K * norm_angle(297.8 + 4452.67 * jy)) rm += 0.0020 * Math.sin(Const::K * norm_angle(247.1 + 329.64 * jy)) rm += 0.0048 * Math.sin(Const::K * norm_angle(234.95 + 19.341 * jy)) rm += 0.0200 * Math.sin(Const::K * norm_angle(355.05 + 719.981 * jy)) rm += (1.9146 - 0.00005 * jy) * Math.sin(Const::K * norm_angle(357.538 + 359.991 * jy)) rm += norm_angle(280.4603 + 360.00769 * jy) return norm_angle(rm) end
compute_last_nc(jd, kbn)
click to toggle source
¶ ↑
直前二分二至・中気時刻の計算 @param: jd (ユリウス日) @param: kbn (90: 二分二至, 30: 中気) @return: [二分二至・中気の時刻, その時の黄経]
¶ ↑
# File lib/mk_calendar/compute.rb, line 664 def compute_last_nc(jd, kbn) jd -= 0.5 # 時刻引数を分解 tm1 = jd.truncate # 整数部分 tm2 = jd - tm1 # 小数部分 tm2 -= Const::JST_D # 直前の二分二至の黄経 λsun0 を求める rm_sun = compute_lambda(jd + 0.5) rm_sun0 = kbn * (rm_sun / kbn.to_f).truncate # 繰り返し計算によって直前の二分二至の時刻を計算する # (誤差が±1.0 sec以内になったら打ち切る。) delta_t1 = 0 ; delta_t2 = 1 while (delta_t1 + delta_t2).abs > (1.0 / 86400.0) # λsun を計算 t = tm1 + tm2 + Const::JST_D + 0.5 rm_sun = compute_lambda(t) # 黄経差 Δλ=λsun -λsun0 delta_rm = rm_sun - rm_sun0 # Δλの引き込み範囲(±180°)を逸脱した場合には、補正を行う case when delta_rm > 180; delta_rm -= 360 when delta_rm < -180; delta_rm += 360 end # 時刻引数の補正値 Δt delta_t1 = (delta_rm * 365.2 / 360.0).truncate delta_t2 = delta_rm * 365.2 / 360.0 - delta_t1 # 時刻引数の補正 tm1 = tm1 - delta_t1 tm2 = tm2 - delta_t2 if tm2 < 0 tm2 += 1 tm1 -= 1 end end # nibun_chu[0] : 時刻引数を合成、DT ==> JST 変換を行い、戻り値とする # ( 補正時刻=0.0sec と仮定して計算 ) # nibun_chu[1] : 黄経 nibun_chu = Array.new(2, 0) nibun_chu[0] = tm2 + 9 / 24.0 nibun_chu[0] += tm1 nibun_chu[1] = rm_sun0 return nibun_chu end
compute_moonage(jd)
click to toggle source
compute_oc(jd)
click to toggle source
¶ ↑
旧暦の計算 * 旧暦一日の六曜 1・7月 : 先勝 2・8月 : 友引 3・9月 : 先負 4・10月 : 仏滅 5・11月 : 大安 6・12月 : 赤口 と決まっていて、あとは月末まで順番通り。 よって、月と日をたした数を6で割った余りによって六曜を決定することができます。 ( 旧暦の月 + 旧暦の日 ) ÷ 6 = ? … 余り 余り 0 : 大安 1 : 赤口 2 : 先勝 3 : 友引 4 : 先負 5 : 仏滅 @param: jd (ユリウス日(JST)) @return: [旧暦年, 閏月Flag, 旧暦月, 旧暦日, 六曜]
¶ ↑
# File lib/mk_calendar/compute.rb, line 476 def compute_oc(jd) jd -= 0.5 tm0 = jd # 二分二至,中気の時刻・黄経用配列宣言 chu = Array.new(4).map { Array.new(2, 0) } # 朔用配列宣言 saku = Array.new(5, 0) # 朔日用配列宣言 m = Array.new(5).map { Array.new(3, 0) } # 旧暦用配列宣言 kyureki = Array.new(4, 0) # 計算対象の直前にあたる二分二至の時刻を計算 # chu[0][0] : 二分二至の時刻 # chu[0][1] : その時の太陽黄経 chu[0] = compute_last_nc(tm0, 90) # 中気の時刻を計算 ( 3回計算する ) # chu[i][0] : 中気の時刻 # chu[i][1] : その時の太陽黄経 1.upto(3) do |i| chu[i] = compute_last_nc(chu[i - 1][0] + 32, 30) end # 計算対象の直前にあたる二分二至の直前の朔の時刻を求める saku[0] = compute_saku(chu[0][0]) # 朔の時刻を求める 1.upto(4) do |i| tm = saku[i-1] + 30 saku[i] = compute_saku(tm) # 前と同じ時刻を計算した場合( 両者の差が26日以内 )には、初期値を # +33日にして再実行させる。 if (saku[i-1].truncate - saku[i].truncate).abs <= 26 saku[i] = compute_saku(saku[i-1] + 35) end end # saku[1]が二分二至の時刻以前になってしまった場合には、朔をさかのぼり過ぎ # たと考えて、朔の時刻を繰り下げて修正する。 # その際、計算もれ(saku[4])になっている部分を補うため、朔の時刻を計算 # する。(近日点通過の近辺で朔があると起こる事があるようだ...?) if saku[1].truncate <= chu[0][0].truncate 0.upto(3) { |i| saku[i] = saku[i+1] } saku[4] = compute_saku(saku[3] + 35) # saku[0]が二分二至の時刻以後になってしまった場合には、朔をさかのぼり足 # りないと見て、朔の時刻を繰り上げて修正する。 # その際、計算もれ(saku[0])になっている部分を補うため、朔の時刻を計算 # する。(春分点の近辺で朔があると起こる事があるようだ...?) elsif saku[0].truncate > chu[0][0].truncate 4.downto(1) { |i| saku[i] = saku[i-1] } saku[0] = compute_saku(saku[0] - 27) end # 閏月検索Flagセット # (節月で4ヶ月の間に朔が5回あると、閏月がある可能性がある。) # leap=0:平月 leap=1:閏月 leap = 0 leap = 1 if saku[4].truncate <= chu[3][0].truncate # 朔日行列の作成 # m[i][0] ... 月名 ( 1:正月 2:2月 3:3月 .... ) # m[i][1] ... 閏フラグ ( 0:平月 1:閏月 ) # m[i][2] ... 朔日のjd m[0][0] = (chu[0][1] / 30.0).truncate + 2 m[0][0] -= 12 if m[0][0] > 12 m[0][2] = saku[0].truncate m[0][1] = 0 1.upto(4) do |i| if leap == 1 && i != 1 if chu[i-1][0].truncate <= saku[i-1].truncate || chu[i-1][0].truncate >= saku[i].truncate m[i-1][0] = m[i-2][0] m[i-1][1] = 1 m[i-1][2] = saku[i-1].truncate leap = 0 end end m[i][0] = m[i-1][0] + 1 m[i][0] -= 12 if m[i][0] > 12 m[i][2] = saku[i].truncate m[i][1] = 0 end # 朔日行列から旧暦を求める。 state, index = 0, 0 0.upto(4) do |i| index = i if tm0.truncate < m[i][2].truncate state = 1 break elsif tm0.truncate == m[i][2].truncate state = 2 break end end index -= 1 if state == 1 kyureki[1] = m[index][1] kyureki[2] = m[index][0] kyureki[3] = tm0.truncate - m[index][2].truncate + 1 # 旧暦年の計算 # (旧暦月が10以上でかつ新暦月より大きい場合には、 # まだ年を越していないはず...) a = jd2ymd(tm0) kyureki[0] = a[0] kyureki[0] -= 1 if kyureki[2] > 9 && kyureki[2] > a[1] # 六曜 kyureki[4] = Const::ROKUYO[(kyureki[2] + kyureki[3]) % 6] return kyureki end
compute_rokuyo(oc_month, oc_day)
click to toggle source
compute_saku(jd)
click to toggle source
¶ ↑
直近の朔の時刻(JST)の計算 @param: jd (ユリウス日) @return: saku (直前の朔の時刻)
¶ ↑
# File lib/mk_calendar/compute.rb, line 740 def compute_saku(jd) lc = 1 # 時刻引数を分解する tm1 = jd.truncate tm2 = jd - tm1 tm2 -= Const::JST_D # 繰り返し計算によって朔の時刻を計算する # (誤差が±1.0 sec以内になったら打ち切る。) delta_t1 = 0 ; delta_t2 = 1 while (delta_t1 + delta_t2).abs > (1.0 / 86400.0) # 太陽の黄経λsun ,月の黄経λmoon を計算 t = tm1 + tm2 + Const::JST_D + 0.5 rm_sun = compute_lambda(t) rm_moon = compute_alpha(t) # 月と太陽の黄経差Δλ # Δλ=λmoon-λsun delta_rm = rm_moon - rm_sun # ループの1回目 ( lc = 1 ) で delta_rm < 0.0 の場合には引き込み範囲に # 入るように補正する if lc == 1 && delta_rm < 0 delta_rm = norm_angle(delta_rm) # 春分の近くで朔がある場合 ( 0 ≦λsun≦ 20 ) で、月の黄経λmoon≧300 の # 場合には、Δλ= 360.0 - Δλ と計算して補正する elsif rm_sun >= 0 && rm_sun <= 20 && rm_moon >= 300 delta_rm = norm_angle(delta_rm) delta_rm = 360 - delta_rm # Δλの引き込み範囲 ( ±40° ) を逸脱した場合には、補正を行う elsif delta_rm.abs > 40.0 delta_rm = norm_angle(delta_rm) end # 時刻引数の補正値 Δt delta_t1 = (delta_rm * 29.530589 / 360.0).truncate delta_t2 = delta_rm * 29.530589 / 360.0 - delta_t1 # 時刻引数の補正 tm1 = tm1 - delta_t1 tm2 = tm2 - delta_t2 if tm2 < 0 tm2 += 1 tm1 -= 1 end # ループ回数が15回になったら、初期値 tm を tm-26 とする。 if lc == 15 && (delta_t1 + delta_t2).abs > (1.0 / 86400.0) tm1 = (jd - 26).truncate tm2 = 0 # 初期値を補正したにも関わらず、振動を続ける場合には初期値を答えとして # 返して強制的にループを抜け出して異常終了させる。 elsif lc > 30 && (delta_t1+delta_t2).abs > (1.0 / 86400.0) tm1 = jd tm2 = 0 break end lc += 1 end # 時刻引数を合成、DT ==> JST 変換を行い、戻り値とする # (補正時刻=0.0sec と仮定して計算) return tm2 + tm1 + 9 / 24.0 end
compute_sekki_24(jd)
click to toggle source
¶ ↑
二十四節気の計算 @param: jd (ユリウス日(JST)) @return: sekki_24 (二十四節気の文字列)
¶ ↑
# File lib/mk_calendar/compute.rb, line 135 def compute_sekki_24(jd) lsun_today = compute_lambda(jd) lsun_tomorrow = compute_lambda(jd + 1) lsun_today0 = 15 * (lsun_today / 15.0).truncate lsun_tomorrow0 = 15 * (lsun_tomorrow / 15.0).truncate return lsun_today0 == lsun_tomorrow0 ? "" : Const::SEKKI_24[lsun_tomorrow0 / 15] end
compute_sekku(month, day)
click to toggle source
compute_yobi(jd)
click to toggle source
compute_zassetsu(jd)
click to toggle source
¶ ↑
雑節の計算 @param: jd (ユリウス日(JST)) @return: [雑節コード1, 雑節コード2]
¶ ↑
# File lib/mk_calendar/compute.rb, line 149 def compute_zassetsu(jd) zassetsu = Array.new # 計算対象日の太陽の黄経 lsun_today = compute_lambda(jd) # 計算対象日の翌日の太陽の黄経 lsun_tomorrow = compute_lambda(jd + 1) # 計算対象日の5日前の太陽の黄経(社日計算用) lsun_before_5 = compute_lambda(jd - 5) # 計算対象日の4日前の太陽の黄経(社日計算用) lsun_before_4 = compute_lambda(jd - 4) # 計算対象日の5日後の太陽の黄経(社日計算用) lsun_after_5 = compute_lambda(jd + 5) # 計算対象日の6日後の太陽の黄経(社日計算用) lsun_after_6 = compute_lambda(jd + 6) # 太陽の黄経の整数部分( 土用, 入梅, 半夏生 計算用 ) lsun_today0 = lsun_today.truncate lsun_tomorrow0 = lsun_tomorrow.truncate #### ここから各種雑節計算 # 0:節分 ( 立春の前日 ) zassetsu << 0 if compute_sekki_24(jd + 1) == "立春" # 1:彼岸入(春) ( 春分の日の3日前 ) zassetsu << 1 if compute_sekki_24(jd + 3) == "春分" # 2:彼岸(春) ( 春分の日 ) zassetsu << 2 if compute_sekki_24(jd) == "春分" # 3:彼岸明(春) ( 春分の日の3日後 ) zassetsu << 3 if compute_sekki_24(jd - 3) == "春分" # 4:社日(春) ( 春分の日に最も近い戊(つちのえ)の日 ) # * 計算対象日が戊の日の時、 # * 4日後までもしくは4日前までに春分の日がある時、 # この日が社日 # * 5日後が春分の日の時、 # * 春分点(黄経0度)が午前なら # この日が社日 # * 春分点(黄経0度)が午後なら # この日の10日後が社日 if (jd % 10).truncate == 4 # 戊の日 # [ 当日から4日後 ] 0.upto(4) do |i| if compute_sekki_24(jd + i) == "春分" zassetsu << 4 break end end # [ 1日前から4日前 ] 1.upto(4) do |i| if compute_sekki_24(jd - i) == "春分" zassetsu << 4 break end end # [ 5日後 ] if compute_sekki_24(jd + 5) == "春分" # 春分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が # 0度(360度)以上なら、春分点が午前と判断 zassetsu << 4 if (lsun_after_5 + lsun_after_6 + 360) / 2.0 >= 360 end # [ 5日前 ] if compute_sekki_24(jd - 5) == "春分" # 春分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が # 0度(360度)未満なら、春分点が午後と判断 zassetsu << 4 if (lsun_before_4 + lsun_before_5 + 360) / 2.0 < 360 end end # 5:土用入(春) ( 黄経(太陽) = 27度 ) unless lsun_today0 == lsun_tomorrow0 zassetsu << 5 if lsun_tomorrow0 == 27 end # 6:八十八夜 ( 立春から88日目(87日後) ) zassetsu << 6 if compute_sekki_24(jd - 87) == "立春" # 7:入梅 ( 黄経(太陽) = 80度 ) unless lsun_today0 == lsun_tomorrow0 zassetsu << 7 if lsun_tomorrow0 == 80 end # 8:半夏生 ( 黄経(太陽) = 100度 ) unless lsun_today0 == lsun_tomorrow0 zassetsu << 8 if lsun_tomorrow0 == 100 end # 9:土用入(夏) ( 黄経(太陽) = 117度 ) unless lsun_today0 == lsun_tomorrow0 zassetsu << 9 if lsun_tomorrow0 == 117 end # 10:二百十日 ( 立春から210日目(209日後) ) zassetsu << 10 if compute_sekki_24(jd - 209) == "立春" # 11:二百二十日 ( 立春から220日目(219日後) ) zassetsu << 11 if compute_sekki_24(jd - 219) == "立春" # 12:彼岸入(秋) ( 秋分の日の3日前 ) zassetsu << 12 if compute_sekki_24(jd + 3) == "秋分" # 13:彼岸(秋) ( 秋分の日 ) zassetsu << 13 if compute_sekki_24(jd) == "秋分" # 14:彼岸明(秋) ( 秋分の日の3日後 ) zassetsu << 14 if compute_sekki_24(jd - 3) == "秋分" # 15:社日(秋) ( 秋分の日に最も近い戊(つちのえ)の日 ) # * 計算対象日が戊の日の時、 # * 4日後までもしくは4日前までに秋分の日がある時、 # この日が社日 # * 5日後が秋分の日の時、 # * 秋分点(黄経180度)が午前なら # この日が社日 # * 秋分点(黄経180度)が午後なら # この日の10日後が社日 if (jd % 10).truncate == 4 # 戊の日 # [ 当日から4日後 ] 0.upto(4) do |i| if compute_sekki_24(jd + i) == "秋分" zassetsu << 15 break end end # [ 1日前から4日前 ] 1.upto(4) do |i| if compute_sekki_24(jd - i) == "秋分" zassetsu << 15 break end end # [ 5日後 ] if compute_sekki_24(jd + 5) == "秋分" # 秋分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が # 180度以上なら、秋分点が午前と判断 zassetsu << 15 if (lsun_after_5 + lsun_after_6) / 2.0 >= 180 end # [ 5日前 ] if compute_sekki_24(jd - 5) == "秋分" # 秋分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が # 180度未満なら、秋分点が午後と判断 zassetsu << 15 if (lsun_before_4 + lsun_before_5) / 2.0 < 180 end end # 16:土用入(秋) ( 黄経(太陽) = 207度 ) unless lsun_today0 == lsun_tomorrow0 zassetsu << 16 if lsun_tomorrow0 == 207 end # 17:土用入(冬) ( 黄経(太陽) = 297度 ) unless lsun_today0 == lsun_tomorrow0 zassetsu << 17 if lsun_tomorrow0 == 297 end return zassetsu.map { |z| Const::ZASSETSU[z] }.join(",") end
gc2jd(year, month, day, hour = 0, min = 0, sec = 0)
click to toggle source
¶ ↑
Gregorian Calendar -> Julian Day * フリーゲルの公式を使用する [ JD ] = int( 365.25 × year ) + int( year / 400 ) - int( year / 100 ) + int( 30.59 ( month - 2 ) ) + day + 1721088 ※上記の int( x ) は厳密には、x を超えない最大の整数 ( ちなみに、[ 準JD ]を求めるなら + 1721088.5 が - 678912 となる ) @param: year @param: month @param: day @param: hour @param: minute @param: second @return: jd ( ユリウス日 )
¶ ↑
# File lib/mk_calendar/compute.rb, line 601 def gc2jd(year, month, day, hour = 0, min = 0, sec = 0) # 1月,2月は前年の13月,14月とする if month < 3 year -= 1 month += 12 end # 日付(整数)部分計算 jd = (365.25 * year).truncate jd += (year / 400.0).truncate jd -= (year / 100.0).truncate jd += (30.59 * (month - 2)).truncate jd += day jd += 1721088.125 # 時間(小数)部分計算 t = sec / 3600.0 t += min / 60.0 t += hour t = t / 24.0 return jd + t end
jd2ymd(jd)
click to toggle source
¶ ↑
Julian Day -> UT @param: jd (ユリウス日) @return: [year, month, day, hour, minute, second]
¶ ↑
# File lib/mk_calendar/compute.rb, line 628 def jd2ymd(jd) ut = Array.new(6, 0) x0 = (jd + 68570).truncate x1 = (x0 / 36524.25).truncate x2 = x0 - (36524.25 * x1 + 0.75).truncate x3 = ((x2 + 1) / 365.2425).truncate x4 = x2 - (365.25 * x3).truncate + 31 x5 = (x4.truncate / 30.59).truncate x6 = (x5.truncate / 11.0).truncate ut[2] = x4 - (30.59 * x5).truncate ut[1] = x5 - 12 * x6 + 2 ut[0] = 100 * (x1 - 49) + x3 + x6 # 2月30日の補正 if ut[1]==2 && ut[2] > 28 if ut[0] % 100 == 0 && ut[0] % 400 == 0 ut[2] = 29 elsif ut[0] % 4 == 0 ut[2] = 29 else ut[2] = 28 end end tm = 86400 * (jd - jd.truncate) ut[3] = (tm / 3600.0).truncate ut[4] = ((tm - 3600 * ut[3]) / 60.0).truncate ut[5] = (tm - 3600 * ut[3] - 60 * ut[4]).truncate return ut end
norm_angle(angle)
click to toggle source
¶ ↑
角度の正規化 @param: angle @return: angle
¶ ↑
# File lib/mk_calendar/compute.rb, line 721 def norm_angle(angle) if angle < 0 angle1 = angle * (-1) angle2 = (angle1 / 360.0).truncate angle1 -= 360 * angle2 angle1 = 360 - angle1 else angle1 = (angle / 360.0).truncate angle1 = angle - 360.0 * angle1 end return angle1 end