mk_calendar 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 02139584649956585473ffba291e3625d8c50525
4
+ data.tar.gz: f4b1574f366b3b07e8139f08732348051d2932d7
5
+ SHA512:
6
+ metadata.gz: 1ac92735c2e5dc386bd46ef7c65ff8c92fbcd7d08db68ca59bb8d2e04d6c1361fbf77af8d7d5b26eca3a4d25834b45f0089d4426989a3a3e6f386f594b526cef
7
+ data.tar.gz: a69690e9412ac04bbdc153474c0afa097e34131e200cf7db02d06173ed9c63a7d3e75b50b4dcd60efb70a0d57de1a3550309233077b4d4e05aeb781f088d5119
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.1
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mk_calendar.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem "guard"
8
+ gem "guard-rspec", "~> 4.7.0"
9
+ end
10
+
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 mk-mode.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # MkCalendar
2
+
3
+ ## Introduction
4
+
5
+ This is the gem library which calculates calendar datas, including old-calendar.
6
+
7
+ ### Computable items
8
+
9
+ julian day(utc), julian day(jst), holiday, sekki_24, zassetsu,
10
+ yobi, kanshi, sekku, lambda_sun, lambda_moon, moonage,
11
+ old-calendar(year, month, day, leap flag), rokuyo
12
+
13
+ ### Original Text
14
+
15
+ [旧暦計算サンプルプログラム](http://www.vector.co.jp/soft/dos/personal/se016093.html)
16
+ Copyright (C) 1993,1994 by H.Takano
17
+
18
+ ### Remark
19
+
20
+ However, the above program includes some problems for calculating the future
21
+ old-calendar datas. So, I have done some adjustments.
22
+
23
+ ## Installation
24
+
25
+ Add this line to your application's Gemfile:
26
+
27
+ ```ruby
28
+ gem 'mk_calendar'
29
+ ```
30
+
31
+ And then execute:
32
+
33
+ $ bundle
34
+
35
+ Or install it yourself as:
36
+
37
+ $ gem install mk_calendar
38
+
39
+ ## Usage
40
+
41
+ ### Instantiation
42
+
43
+ ``` ruby
44
+ require 'mk_calendar'
45
+
46
+ obj = MkCalendar.new
47
+
48
+ # Otherwise
49
+ obj = MkCalendar.new("20160608")
50
+ ```
51
+
52
+ ### Calculation
53
+
54
+ ``` ruby
55
+ obj.calc
56
+
57
+ # Otherwise
58
+ obj.calc_holiday
59
+ obj.calc_sekki_24
60
+ obj.calc_zassetsu
61
+ obj.calc_yobi
62
+ obj.calc_kanshi
63
+ obj.calc_sekku
64
+ obj.calc_lambda_sun
65
+ obj.calc_lambda_moon
66
+ obj.calc_moonage
67
+ obj.calc_oc
68
+ obj.calc_rokuyo
69
+ ```
70
+
71
+ ### Getting values
72
+
73
+ ``` ruby
74
+ puts o.year, o.month, o.day, o.jd, o.jd_jst
75
+ puts o.holiday
76
+ puts o.sekki_24
77
+ puts o.zassetsu
78
+ puts o.yobi
79
+ puts o.kanshi
80
+ puts o.sekku
81
+ puts o.lambda_sun
82
+ puts o.lambda_moon
83
+ puts o.moonage
84
+ puts o.oc_year, o.oc_leap, o.oc_month, o.oc_day
85
+ puts o.rokuyo
86
+ ```
87
+
88
+ ## Development
89
+
90
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec mk_calendar` to use the gem in this directory, ignoring other installed copies of this gem.
91
+
92
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
93
+
94
+ ## Contributing
95
+
96
+ Bug reports and pull requests are welcome on GitHub at https://github.com/komasaru/mk_calendar.
97
+
98
+
99
+ ## License
100
+
101
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
102
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mk_calendar"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/mk_calendar ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "mk_calendar"
4
+
5
+ o = MkCalendar.new(ARGV[0])
6
+ exit unless o
7
+ o.calc
8
+ str = sprintf("%04d-%02d-%02d", o.year, o.month, o.day)
9
+ str << " #{o.yobi}曜日"
10
+ str << " #{o.holiday}" unless o.holiday == ""
11
+ str << " #{o.jd}UTC(#{o.jd_jst}JST) #{o.kanshi} "
12
+ str << sprintf("%04d-%02d-%02d", o.oc_year, o.oc_month, o.oc_day)
13
+ str << "(閏)" if o.oc_leap == 1
14
+ str << " #{o.rokuyo}"
15
+ str << " #{o.sekki_24}" unless o.sekki_24 == ""
16
+ str << " #{o.zassetsu}" unless o.zassetsu == ""
17
+ str << " #{o.sekku}" unless o.sekku == ""
18
+ str << " #{o.lambda_sun} #{o.lambda_moon} #{o.moonage}"
19
+ puts str
20
+
21
+ # Calculation for each
22
+ #p o.year, o.month, o.day, o.jd, o.jd_jst
23
+ #o.calc_holiday ; puts o.holiday
24
+ #o.calc_sekki_24 ; puts o.sekki_24
25
+ #o.calc_zassetsu ; puts o.zassetsu
26
+ #o.calc_yobi ; puts o.yobi
27
+ #o.calc_kanshi ; puts o.kanshi
28
+ #o.calc_sekku ; puts o.sekku
29
+ #o.calc_lambda_sun ; puts o.lambda_sun
30
+ #o.calc_lambda_moon; puts o.lambda_moon
31
+ #o.calc_moonage ; puts o.moonage
32
+ #o.calc_oc ; puts o.oc_year, o.oc_leap, o.oc_month, o.oc_day
33
+ #o.calc_rokuyo ; puts o.rokuyo
34
+
@@ -0,0 +1,30 @@
1
+ module MkCalendar
2
+ class Argument
3
+ def initialize(arg)
4
+ @date = arg
5
+ end
6
+
7
+ #=========================================================================
8
+ # 引数取得
9
+ #
10
+ # * コマンドライン引数を取得して日時の妥当性チェックを行う
11
+ # * コマンドライン引数無指定なら、現在日とする。
12
+ #
13
+ # @return: jst (UNIX time)
14
+ #=========================================================================
15
+ def get_ymd
16
+ unless @date =~ /^\d{8}$/
17
+ puts Const::USAGE
18
+ return []
19
+ end
20
+ year = @date[0,4].to_i
21
+ month = @date[4,2].to_i
22
+ day = @date[6,2].to_i
23
+ unless Date.valid_date?(year, month, day)
24
+ puts Const::MSG_ERR_1
25
+ return []
26
+ end
27
+ return [year, month, day]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,1137 @@
1
+ module MkCalendar
2
+ class Calendar
3
+ attr_reader :year, :month, :day, :jd, :jd_jst,
4
+ :holiday, :sekki_24, :zassetsu, :yobi, :kanshi, :sekku,
5
+ :lambda_sun, :lambda_moon, :moonage,
6
+ :oc_year, :oc_leap, :oc_month, :oc_day, :rokuyo
7
+
8
+ def initialize(ymd)
9
+ @year, @month, @day = ymd
10
+ @jd = gc2jd(@year, @month, @day)
11
+ @jd_jst = @jd + Const::JST_D
12
+ end
13
+
14
+ #=========================================================================
15
+ # 各種計算のコール(一括)
16
+ #=========================================================================
17
+ def calc
18
+ @holiday = compute_holiday
19
+ @sekki_24 = compute_sekki_24
20
+ @zassetsu = compute_zassetsu
21
+ @yobi = compute_yobi
22
+ @kanshi = compute_kanshi
23
+ @sekku = compute_sekku
24
+ @lambda_sun = compute_lambda_sun
25
+ @lambda_moon = compute_lambda_moon
26
+ @moonage = compute_moonage
27
+ @oc_year, @oc_leap, @oc_month, @oc_day = compute_oc
28
+ @rokuyo = compute_rokuyo
29
+ end
30
+
31
+ #=========================================================================
32
+ # 「休日」計算のコール
33
+ #=========================================================================
34
+ def calc_holiday
35
+ @holiday = compute_holiday
36
+ end
37
+
38
+ #=========================================================================
39
+ # 「二十四節気」計算のコール
40
+ #=========================================================================
41
+ def calc_sekki_24
42
+ @sekki_24 = compute_sekki_24
43
+ end
44
+
45
+ #=========================================================================
46
+ # 「雑節」計算のコール
47
+ #=========================================================================
48
+ def calc_zassetsu
49
+ @zassetsu = compute_zassetsu
50
+ end
51
+
52
+ #=========================================================================
53
+ # 「曜日」計算のコール
54
+ #=========================================================================
55
+ def calc_yobi
56
+ @yobi = compute_yobi
57
+ end
58
+
59
+ #=========================================================================
60
+ # 「干支」計算のコール
61
+ #=========================================================================
62
+ def calc_kanshi
63
+ @kanshi = compute_kanshi
64
+ end
65
+
66
+ #=========================================================================
67
+ # 「節句」計算のコール
68
+ #=========================================================================
69
+ def calc_sekku
70
+ @sekku = compute_sekku
71
+ end
72
+
73
+ #=========================================================================
74
+ # 「視黄経(太陽)」計算のコール
75
+ #=========================================================================
76
+ def calc_lambda_sun
77
+ @lambda_sun = compute_lambda_sun
78
+ end
79
+
80
+ #=========================================================================
81
+ # 「視黄経(月)」計算のコール
82
+ #=========================================================================
83
+ def calc_lambda_moon
84
+ @lambda_moon = compute_lambda_moon
85
+ end
86
+
87
+ #=========================================================================
88
+ # 「月齢(正午)」計算のコール
89
+ #=========================================================================
90
+ def calc_moonage
91
+ @moonage = compute_moonage
92
+ end
93
+
94
+ #=========================================================================
95
+ # 「旧暦」計算のコール
96
+ #=========================================================================
97
+ def calc_oc
98
+ @oc_year, @oc_leap, @oc_month, @oc_day = compute_oc
99
+ end
100
+
101
+ #=========================================================================
102
+ # 「六曜」計算のコール
103
+ #=========================================================================
104
+ def calc_rokuyo
105
+ @oc_year, @oc_leap, @oc_month, @oc_day = compute_oc unless @oc_year
106
+ @rokuyo = compute_rokuyo
107
+ end
108
+
109
+ private
110
+
111
+ #=========================================================================
112
+ # 以下、実際の計算
113
+ #=========================================================================
114
+
115
+ #=========================================================================
116
+ # 休日の計算
117
+ #
118
+ # @param: year
119
+ # @return: holiday (漢字1文字)
120
+ #=========================================================================
121
+ def compute_holiday(year = @year)
122
+ holiday_0 = Array.new # 変動の祝日用
123
+ holiday_1 = Array.new # 国民の休日用
124
+ holiday_2 = Array.new # 振替休日用
125
+
126
+ # 変動の祝日の日付・曜日を計算 ( 振替休日,国民の休日を除く )
127
+ Const::HOLIDAY.each do |holiday|
128
+ unless holiday[1] == 99
129
+ unless holiday[2] == 99 # 月日が既定のもの
130
+ jd_jst = gc2jd(year, holiday[1], holiday[2]) + Const::JST_D
131
+ yobi = compute_yobi(jd_jst)
132
+ holiday_0 << [holiday[1], holiday[2], holiday[0], jd_jst, yobi]
133
+ else # 月日が不定のもの
134
+ if holiday[3] == 21 # 第2月曜日 ( 8 - 14 の月曜日)
135
+ 8.upto(14) do |d|
136
+ jd_jst = gc2jd(year, holiday[1], d) + Const::JST_D
137
+ yobi = compute_yobi(jd_jst)
138
+ holiday_0 << [holiday[1], d, holiday[0], jd_jst, "月"] if yobi == "月"
139
+ end
140
+ elsif holiday[3] == 31 # 第3月曜日 ( 15 - 21 の月曜日)
141
+ 15.upto(21) do |d|
142
+ jd_jst = gc2jd(year, holiday[1], d) + Const::JST_D
143
+ yobi = compute_yobi(jd_jst)
144
+ holiday_0 << [holiday[1], d, holiday[0], jd_jst, "月"] if yobi == "月"
145
+ end
146
+ elsif holiday[3] == 80 # 春分の日
147
+ jd_jst = gc2jd(year, holiday[1], 31) + Const::JST_D
148
+ nibun_jd = compute_last_nc(jd_jst, 90)[0]
149
+ d = jd2ymd(nibun_jd)[2]
150
+ wk_jd = gc2jd(year, holiday[1], d) + Const::JST_D
151
+ yobi = compute_yobi(wk_jd)
152
+ holiday_0 << [holiday[1], d, holiday[0], wk_jd, yobi]
153
+ elsif holiday[3] == 81 # 秋分の日
154
+ jd_jst = gc2jd(year, holiday[1], 30) + Const::JST_D
155
+ nibun_jd = compute_last_nc(jd_jst, 90)[0]
156
+ d = jd2ymd(nibun_jd)[2]
157
+ wk_jd = gc2jd(year, holiday[1], d) + Const::JST_D
158
+ yobi = compute_yobi(wk_jd)
159
+ holiday_0 << [holiday[1], d, holiday[0], wk_jd, yobi]
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ # 国民の休日計算
166
+ # ( 「国民の祝日」で前後を挟まれた「国民の祝日」でない日 )
167
+ # ( 年またぎは考慮していない(今のところ不要) )
168
+ 0.upto(holiday_0.length - 2) do |i|
169
+ if holiday_0[i][3] + 2 == holiday_0[i + 1][3]
170
+ jd = holiday_0[i][3] + 1
171
+ #yobi = (holiday_0[i][4] + 1) == 7 ? 0 : (holiday_0[i][4] + 1)
172
+ yobi = Const::YOBI[Const::YOBI.index(holiday_0[i][4]) + 1]
173
+ wk_ary = Array.new
174
+ wk_ary << jd2ymd(jd)[1]
175
+ wk_ary << jd2ymd(jd)[2]
176
+ wk_ary << 90
177
+ wk_ary << jd
178
+ wk_ary << yobi
179
+ holiday_1 << wk_ary
180
+ end
181
+ end
182
+
183
+ # 振替休日計算
184
+ # ( 「国民の祝日」が日曜日に当たるときは、
185
+ # その日後においてその日に最も近い「国民の祝日」でない日 )
186
+ 0.upto(holiday_0.length - 1) do |i|
187
+ if holiday_0[i][4] == 0
188
+ next_jd = holiday_0[i][3] + 1
189
+ #next_yobi = (holiday_0[i][4] + 1) == 7 ? 0 : (holiday_0[i][4] + 1)
190
+ next_yobi = Const::YOBI[Const::YOBI.index(holiday_0[i][4]) + 1]
191
+ if i == holiday_0.length - 1
192
+ wk_ary = Array.new
193
+ wk_ary << jd2ymd(next_jd)[1]
194
+ wk_ary << jd2ymd(next_jd)[2]
195
+ wk_ary << 91
196
+ wk_ary << next_jd
197
+ wk_ary << next_yobi
198
+ else
199
+ flg_furikae = 0
200
+ plus_day = 1
201
+ while flg_furikae == 0
202
+ if i + plus_day < holiday_0.length
203
+ if next_jd == holiday_0[i + plus_day][3]
204
+ next_jd += 1
205
+ next_yobi = (next_yobi + 1) == 7 ? 0 : (next_yobi + 1)
206
+ plus_day += 1
207
+ else
208
+ flg_furikae = 1
209
+ wk_ary = Array.new
210
+ wk_ary << jd2(next_jd)[1]
211
+ wk_ary << jd2(next_jd)[2]
212
+ wk_ary << 91
213
+ wk_ary << next_jd
214
+ wk_ary << next_yobi
215
+ end
216
+ end
217
+ end
218
+ end
219
+ holiday_2 << wk_ary
220
+ end
221
+ end
222
+
223
+ # 配列整理
224
+ code = 99
225
+ (holiday_0 + holiday_1 + holiday_2).sort.each do |holiday|
226
+ if holiday[0] == month && holiday[1] == day
227
+ code = holiday[2]
228
+ break
229
+ end
230
+ end
231
+ holiday = ""
232
+ res = Const::HOLIDAY.select { |h| h[0] == code }
233
+ holiday = res[0][4] unless res == []
234
+ return holiday
235
+ end
236
+
237
+ #=========================================================================
238
+ # 二十四節気の計算
239
+ #
240
+ # @param: jd (ユリウス日(JST))
241
+ # @return: sekki_24 (二十四節気の文字列)
242
+ #=========================================================================
243
+ def compute_sekki_24(jd = @jd_jst)
244
+ lsun_today = compute_lambda_sun(jd)
245
+ lsun_tomorrow = compute_lambda_sun(jd + 1)
246
+ lsun_today0 = 15 * (lsun_today / 15.0).truncate
247
+ lsun_tomorrow0 = 15 * (lsun_tomorrow / 15.0).truncate
248
+ return lsun_today0 == lsun_tomorrow0 ? "" : Const::SEKKI_24[lsun_tomorrow0 / 15]
249
+ end
250
+
251
+ #=========================================================================
252
+ # 雑節の計算
253
+ #
254
+ # @param: jd (ユリウス日(JST))
255
+ # @return: [雑節コード1, 雑節コード2]
256
+ #=========================================================================
257
+ def compute_zassetsu(jd = @jd_jst)
258
+ zassetsu = Array.new
259
+
260
+ # 計算対象日の太陽の黄経
261
+ lsun_today = compute_lambda_sun(jd)
262
+ # 計算対象日の翌日の太陽の黄経
263
+ lsun_tomorrow = compute_lambda_sun(jd + 1)
264
+ # 計算対象日の5日前の太陽の黄経(社日計算用)
265
+ lsun_before_5 = compute_lambda_sun(jd - 5)
266
+ # 計算対象日の4日前の太陽の黄経(社日計算用)
267
+ lsun_before_4 = compute_lambda_sun(jd - 4)
268
+ # 計算対象日の5日後の太陽の黄経(社日計算用)
269
+ lsun_after_5 = compute_lambda_sun(jd + 5)
270
+ # 計算対象日の6日後の太陽の黄経(社日計算用)
271
+ lsun_after_6 = compute_lambda_sun(jd + 6)
272
+ # 太陽の黄経の整数部分( 土用, 入梅, 半夏生 計算用 )
273
+ lsun_today0 = lsun_today.truncate
274
+ lsun_tomorrow0 = lsun_tomorrow.truncate
275
+
276
+ #### ここから各種雑節計算
277
+ # 0:節分 ( 立春の前日 )
278
+ zassetsu << 0 if compute_sekki_24(jd + 1) == "立春"
279
+ # 1:彼岸入(春) ( 春分の日の3日前 )
280
+ zassetsu << 1 if compute_sekki_24(jd + 3) == "春分"
281
+ # 2:彼岸(春) ( 春分の日 )
282
+ zassetsu << 2 if compute_sekki_24(jd) == "春分"
283
+ # 3:彼岸明(春) ( 春分の日の3日後 )
284
+ zassetsu << 3 if compute_sekki_24(jd - 3) == "春分"
285
+ # 4:社日(春) ( 春分の日に最も近い戊(つちのえ)の日 )
286
+ # * 計算対象日が戊の日の時、
287
+ # * 4日後までもしくは4日前までに春分の日がある時、
288
+ # この日が社日
289
+ # * 5日後が春分の日の時、
290
+ # * 春分点(黄経0度)が午前なら
291
+ # この日が社日
292
+ # * 春分点(黄経0度)が午後なら
293
+ # この日の10日後が社日
294
+ if (jd % 10).truncate == 4 # 戊の日
295
+ # [ 当日から4日後 ]
296
+ 0.upto(4) do |i|
297
+ if compute_sekki_24(jd + i) == "春分"
298
+ zassetsu << 4
299
+ break
300
+ end
301
+ end
302
+ # [ 1日前から4日前 ]
303
+ 1.upto(4) do |i|
304
+ if compute_sekki_24(jd - i) == "春分"
305
+ zassetsu << 4
306
+ break
307
+ end
308
+ end
309
+ # [ 5日後 ]
310
+ if compute_sekki_24(jd + 5) == "春分"
311
+ # 春分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
312
+ # 0度(360度)以上なら、春分点が午前と判断
313
+ zassetsu << 4 if (lsun_after_5 + lsun_after_6 + 360) / 2.0 >= 360
314
+ end
315
+ # [ 5日前 ]
316
+ if compute_sekki_24(jd - 5) == "春分"
317
+ # 春分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
318
+ # 0度(360度)未満なら、春分点が午後と判断
319
+ zassetsu << 4 if (lsun_before_4 + lsun_before_5 + 360) / 2.0 < 360
320
+ end
321
+ end
322
+ # 5:土用入(春) ( 黄経(太陽) = 27度 )
323
+ unless lsun_today0 == lsun_tomorrow0
324
+ zassetsu << 5 if lsun_tomorrow0 == 27
325
+ end
326
+ # 6:八十八夜 ( 立春から88日目(87日後) )
327
+ zassetsu << 6 if compute_sekki_24(jd - 87) == "立春"
328
+ # 7:入梅 ( 黄経(太陽) = 80度 )
329
+ unless lsun_today0 == lsun_tomorrow0
330
+ zassetsu << 7 if lsun_tomorrow0 == 80
331
+ end
332
+ # 8:半夏生 ( 黄経(太陽) = 100度 )
333
+ unless lsun_today0 == lsun_tomorrow0
334
+ zassetsu << 8 if lsun_tomorrow0 == 100
335
+ end
336
+ # 9:土用入(夏) ( 黄経(太陽) = 117度 )
337
+ unless lsun_today0 == lsun_tomorrow0
338
+ zassetsu << 9 if lsun_tomorrow0 == 117
339
+ end
340
+ # 10:二百十日 ( 立春から210日目(209日後) )
341
+ zassetsu << 10 if compute_sekki_24(jd - 209) == "立春"
342
+ # 11:二百二十日 ( 立春から220日目(219日後) )
343
+ zassetsu << 11 if compute_sekki_24(jd - 219) == "立春"
344
+ # 12:彼岸入(秋) ( 秋分の日の3日前 )
345
+ zassetsu << 12 if compute_sekki_24(jd + 3) == "秋分"
346
+ # 13:彼岸(秋) ( 秋分の日 )
347
+ zassetsu << 13 if compute_sekki_24(jd) == "秋分"
348
+ # 14:彼岸明(秋) ( 秋分の日の3日後 )
349
+ zassetsu << 14 if compute_sekki_24(jd - 3) == "秋分"
350
+ # 15:社日(秋) ( 秋分の日に最も近い戊(つちのえ)の日 )
351
+ # * 計算対象日が戊の日の時、
352
+ # * 4日後までもしくは4日前までに秋分の日がある時、
353
+ # この日が社日
354
+ # * 5日後が秋分の日の時、
355
+ # * 秋分点(黄経180度)が午前なら
356
+ # この日が社日
357
+ # * 秋分点(黄経180度)が午後なら
358
+ # この日の10日後が社日
359
+ if (jd % 10).truncate == 4 # 戊の日
360
+ # [ 当日から4日後 ]
361
+ 0.upto(4) do |i|
362
+ if compute_sekki_24(jd + i) == "秋分"
363
+ zassetsu << 15
364
+ break
365
+ end
366
+ end
367
+ # [ 1日前から4日前 ]
368
+ 1.upto(4) do |i|
369
+ if compute_sekki_24(jd - i) == "秋分"
370
+ zassetsu << 15
371
+ break
372
+ end
373
+ end
374
+ # [ 5日後 ]
375
+ if compute_sekki_24(jd + 5) == "秋分"
376
+ # 秋分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
377
+ # 180度以上なら、秋分点が午前と判断
378
+ zassetsu << 15 if (lsun_after_5 + lsun_after_6) / 2.0 >= 180
379
+ end
380
+ # [ 5日前 ]
381
+ if compute_sekki_24(jd - 5) == "秋分"
382
+ # 秋分の日の黄経(太陽)と翌日の黄経(太陽)の中間点が
383
+ # 180度未満なら、秋分点が午後と判断
384
+ zassetsu << 15 if (lsun_before_4 + lsun_before_5) / 2.0 < 180
385
+ end
386
+ end
387
+ # 16:土用入(秋) ( 黄経(太陽) = 207度 )
388
+ unless lsun_today0 == lsun_tomorrow0
389
+ zassetsu << 16 if lsun_tomorrow0 == 207
390
+ end
391
+ # 17:土用入(冬) ( 黄経(太陽) = 297度 )
392
+ unless lsun_today0 == lsun_tomorrow0
393
+ zassetsu << 17 if lsun_tomorrow0 == 297
394
+ end
395
+ return zassetsu.map { |z| Const::ZASSETSU[z] }.join(",")
396
+ end
397
+
398
+ #=========================================================================
399
+ # 曜日の計算
400
+ #
401
+ # * 曜日 = ( ユリウス通日 + 2 ) % 7
402
+ # 0: 日曜, 1: 月曜, 2: 火曜, 3: 水曜, 4: 木曜, 5: 金曜, 6: 土曜
403
+ #
404
+ # @param: jd (ユリウス日(JST))
405
+ # @return: yobi (漢字1文字)
406
+ #=========================================================================
407
+ def compute_yobi(jd = @jd_jst)
408
+ return Const::YOBI[(jd.to_i + 2) % 7]
409
+ end
410
+
411
+ #=========================================================================
412
+ # 干支の計算
413
+ #
414
+ # * [ユリウス日(JST) - 10日] を60で割った剰余
415
+ #
416
+ # @param: jd (ユリウス日(JST))
417
+ # @return kanshi (漢字2文字)
418
+ #=========================================================================
419
+ def compute_kanshi(jd = @jd_jst)
420
+ return Const::KANSHI[(jd.to_i - 10) % 60]
421
+ end
422
+
423
+ #=========================================================================
424
+ # 節句の計算
425
+ #
426
+ # @param: month
427
+ # @param: day
428
+ # @return: sekku (日本語文字列)
429
+ #=========================================================================
430
+ def compute_sekku(month = @month, day = @day)
431
+ sekku = ""
432
+ res = Const::SEKKU.select { |s| s[1] == month && s[2] == day }
433
+ sekku = res[0][3] unless res == []
434
+ return sekku
435
+ end
436
+
437
+ #=========================================================================
438
+ # 太陽視黄経の計算
439
+ #
440
+ # @param: jd (ユリウス日(JST))
441
+ # @return: lambda
442
+ #=========================================================================
443
+ def compute_lambda_sun(jd = @jd_jst)
444
+ year, month, day, hour, min, sec = jd2ymd(jd - 0.5)
445
+ t = (hour * 3600 + min * 60 + sec) / 86400.0
446
+ dt = compute_dt(year, month, day) # deltaT
447
+ dp = gc2j2000(year, month, day) # 2000年1月1日力学時正午からの経過日数(日)計算
448
+ jy = (t + dp + dt / 86400.0) / 365.25 # Julian Year
449
+ rm = 0.0003 * Math.sin(Const::K * norm_angle(329.7 + 44.43 * jy))
450
+ rm += 0.0003 * Math.sin(Const::K * norm_angle(352.5 + 1079.97 * jy))
451
+ rm += 0.0004 * Math.sin(Const::K * norm_angle( 21.1 + 720.02 * jy))
452
+ rm += 0.0004 * Math.sin(Const::K * norm_angle(157.3 + 299.30 * jy))
453
+ rm += 0.0004 * Math.sin(Const::K * norm_angle(234.9 + 315.56 * jy))
454
+ rm += 0.0005 * Math.sin(Const::K * norm_angle(291.2 + 22.81 * jy))
455
+ rm += 0.0005 * Math.sin(Const::K * norm_angle(207.4 + 1.50 * jy))
456
+ rm += 0.0006 * Math.sin(Const::K * norm_angle( 29.8 + 337.18 * jy))
457
+ rm += 0.0007 * Math.sin(Const::K * norm_angle(206.8 + 30.35 * jy))
458
+ rm += 0.0007 * Math.sin(Const::K * norm_angle(153.3 + 90.38 * jy))
459
+ rm += 0.0008 * Math.sin(Const::K * norm_angle(132.5 + 659.29 * jy))
460
+ rm += 0.0013 * Math.sin(Const::K * norm_angle( 81.4 + 225.18 * jy))
461
+ rm += 0.0015 * Math.sin(Const::K * norm_angle(343.2 + 450.37 * jy))
462
+ rm += 0.0018 * Math.sin(Const::K * norm_angle(251.3 + 0.20 * jy))
463
+ rm += 0.0018 * Math.sin(Const::K * norm_angle(297.8 + 4452.67 * jy))
464
+ rm += 0.0020 * Math.sin(Const::K * norm_angle(247.1 + 329.64 * jy))
465
+ rm += 0.0048 * Math.sin(Const::K * norm_angle(234.95 + 19.341 * jy))
466
+ rm += 0.0200 * Math.sin(Const::K * norm_angle(355.05 + 719.981 * jy))
467
+ rm += (1.9146 - 0.00005 * jy) * Math.sin(Const::K * norm_angle(357.538 + 359.991 * jy))
468
+ rm += norm_angle(280.4603 + 360.00769 * jy)
469
+ return norm_angle(rm)
470
+ end
471
+
472
+ #=========================================================================
473
+ # 月視黄経の計算
474
+ #
475
+ # @param: jd (ユリウス日(JST))
476
+ # @return: lambda
477
+ #=========================================================================
478
+ def compute_lambda_moon(jd = @jd_jst)
479
+ year, month, day, hour, min, sec = jd2ymd(jd - 0.5)
480
+ t = (hour * 60 * 60 + min * 60 + sec) / 86400.0
481
+ dt = compute_dt(year, month, day) # deltaT
482
+ dp = gc2j2000(year, month, day) # 2000年1月1日力学時正午からの経過日数(日)計算
483
+ jy = (t + dp + dt / 86400.0) / 365.25 # Julian Year
484
+ am = 0.0006 * Math.sin(Const::K * norm_angle( 54.0 + 19.3 * jy))
485
+ am += 0.0006 * Math.sin(Const::K * norm_angle( 71.0 + 0.2 * jy))
486
+ am += 0.0020 * Math.sin(Const::K * norm_angle( 55.0 + 19.34 * jy))
487
+ am += 0.0040 * Math.sin(Const::K * norm_angle(119.5 + 1.33 * jy))
488
+ rm_moon = 0.0003 * Math.sin(Const::K * norm_angle(280.0 + 23221.3 * jy))
489
+ rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(161.0 + 40.7 * jy))
490
+ rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(311.0 + 5492.0 * jy))
491
+ rm_moon += 0.0003 * Math.sin(Const::K * norm_angle(147.0 + 18089.3 * jy))
492
+ rm_moon += 0.0003 * Math.sin(Const::K * norm_angle( 66.0 + 3494.7 * jy))
493
+ rm_moon += 0.0003 * Math.sin(Const::K * norm_angle( 83.0 + 3814.0 * jy))
494
+ rm_moon += 0.0004 * Math.sin(Const::K * norm_angle( 20.0 + 720.0 * jy))
495
+ rm_moon += 0.0004 * Math.sin(Const::K * norm_angle( 71.0 + 9584.7 * jy))
496
+ rm_moon += 0.0004 * Math.sin(Const::K * norm_angle(278.0 + 120.1 * jy))
497
+ rm_moon += 0.0004 * Math.sin(Const::K * norm_angle(313.0 + 398.7 * jy))
498
+ rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(332.0 + 5091.3 * jy))
499
+ rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(114.0 + 17450.7 * jy))
500
+ rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(181.0 + 19088.0 * jy))
501
+ rm_moon += 0.0005 * Math.sin(Const::K * norm_angle(247.0 + 22582.7 * jy))
502
+ rm_moon += 0.0006 * Math.sin(Const::K * norm_angle(128.0 + 1118.7 * jy))
503
+ rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(216.0 + 278.6 * jy))
504
+ rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(275.0 + 4853.3 * jy))
505
+ rm_moon += 0.0007 * Math.sin(Const::K * norm_angle(140.0 + 4052.0 * jy))
506
+ rm_moon += 0.0008 * Math.sin(Const::K * norm_angle(204.0 + 7906.7 * jy))
507
+ rm_moon += 0.0008 * Math.sin(Const::K * norm_angle(188.0 + 14037.3 * jy))
508
+ rm_moon += 0.0009 * Math.sin(Const::K * norm_angle(218.0 + 8586.0 * jy))
509
+ rm_moon += 0.0011 * Math.sin(Const::K * norm_angle(276.5 + 19208.02 * jy))
510
+ rm_moon += 0.0012 * Math.sin(Const::K * norm_angle(339.0 + 12678.71 * jy))
511
+ rm_moon += 0.0016 * Math.sin(Const::K * norm_angle(242.2 + 18569.38 * jy))
512
+ rm_moon += 0.0018 * Math.sin(Const::K * norm_angle( 4.1 + 4013.29 * jy))
513
+ rm_moon += 0.0020 * Math.sin(Const::K * norm_angle( 55.0 + 19.34 * jy))
514
+ rm_moon += 0.0021 * Math.sin(Const::K * norm_angle(105.6 + 3413.37 * jy))
515
+ rm_moon += 0.0021 * Math.sin(Const::K * norm_angle(175.1 + 719.98 * jy))
516
+ rm_moon += 0.0021 * Math.sin(Const::K * norm_angle( 87.5 + 9903.97 * jy))
517
+ rm_moon += 0.0022 * Math.sin(Const::K * norm_angle(240.6 + 8185.36 * jy))
518
+ rm_moon += 0.0024 * Math.sin(Const::K * norm_angle(252.8 + 9224.66 * jy))
519
+ rm_moon += 0.0024 * Math.sin(Const::K * norm_angle(211.9 + 988.63 * jy))
520
+ rm_moon += 0.0026 * Math.sin(Const::K * norm_angle(107.2 + 13797.39 * jy))
521
+ rm_moon += 0.0027 * Math.sin(Const::K * norm_angle(272.5 + 9183.99 * jy))
522
+ rm_moon += 0.0037 * Math.sin(Const::K * norm_angle(349.1 + 5410.62 * jy))
523
+ rm_moon += 0.0039 * Math.sin(Const::K * norm_angle(111.3 + 17810.68 * jy))
524
+ rm_moon += 0.0040 * Math.sin(Const::K * norm_angle(119.5 + 1.33 * jy))
525
+ rm_moon += 0.0040 * Math.sin(Const::K * norm_angle(145.6 + 18449.32 * jy))
526
+ rm_moon += 0.0040 * Math.sin(Const::K * norm_angle( 13.2 + 13317.34 * jy))
527
+ rm_moon += 0.0048 * Math.sin(Const::K * norm_angle(235.0 + 19.34 * jy))
528
+ rm_moon += 0.0050 * Math.sin(Const::K * norm_angle(295.4 + 4812.66 * jy))
529
+ rm_moon += 0.0052 * Math.sin(Const::K * norm_angle(197.2 + 319.32 * jy))
530
+ rm_moon += 0.0068 * Math.sin(Const::K * norm_angle( 53.2 + 9265.33 * jy))
531
+ rm_moon += 0.0079 * Math.sin(Const::K * norm_angle(278.2 + 4493.34 * jy))
532
+ rm_moon += 0.0085 * Math.sin(Const::K * norm_angle(201.5 + 8266.71 * jy))
533
+ rm_moon += 0.0100 * Math.sin(Const::K * norm_angle( 44.89 + 14315.966 * jy))
534
+ rm_moon += 0.0107 * Math.sin(Const::K * norm_angle(336.44 + 13038.696 * jy))
535
+ rm_moon += 0.0110 * Math.sin(Const::K * norm_angle(231.59 + 4892.052 * jy))
536
+ rm_moon += 0.0125 * Math.sin(Const::K * norm_angle(141.51 + 14436.029 * jy))
537
+ rm_moon += 0.0153 * Math.sin(Const::K * norm_angle(130.84 + 758.698 * jy))
538
+ rm_moon += 0.0305 * Math.sin(Const::K * norm_angle(312.49 + 5131.979 * jy))
539
+ rm_moon += 0.0348 * Math.sin(Const::K * norm_angle(117.84 + 4452.671 * jy))
540
+ rm_moon += 0.0410 * Math.sin(Const::K * norm_angle(137.43 + 4411.998 * jy))
541
+ rm_moon += 0.0459 * Math.sin(Const::K * norm_angle(238.18 + 8545.352 * jy))
542
+ rm_moon += 0.0533 * Math.sin(Const::K * norm_angle( 10.66 + 13677.331 * jy))
543
+ rm_moon += 0.0572 * Math.sin(Const::K * norm_angle(103.21 + 3773.363 * jy))
544
+ rm_moon += 0.0588 * Math.sin(Const::K * norm_angle(214.22 + 638.635 * jy))
545
+ rm_moon += 0.1143 * Math.sin(Const::K * norm_angle( 6.546 + 9664.0404 * jy))
546
+ rm_moon += 0.1856 * Math.sin(Const::K * norm_angle(177.525 + 359.9905 * jy))
547
+ rm_moon += 0.2136 * Math.sin(Const::K * norm_angle(269.926 + 9543.9773 * jy))
548
+ rm_moon += 0.6583 * Math.sin(Const::K * norm_angle(235.700 + 8905.3422 * jy))
549
+ rm_moon += 1.2740 * Math.sin(Const::K * norm_angle(100.738 + 4133.3536 * jy))
550
+ rm_moon += 6.2887 * Math.sin(Const::K * norm_angle(134.961 + 4771.9886 * jy + am))
551
+ rm_moon += norm_angle(218.3161 + 4812.67881 * jy)
552
+ return norm_angle(rm_moon)
553
+ end
554
+
555
+ #=========================================================================
556
+ # 月齢(正午)の計算
557
+ #
558
+ # @param: jd (ユリウス日(JST))
559
+ # @return: moonage
560
+ #=========================================================================
561
+ def compute_moonage(jd = @jd_jst)
562
+ return jd - compute_saku(jd)
563
+ end
564
+
565
+ #=========================================================================
566
+ # 旧暦の計算
567
+ #
568
+ # @return: [旧暦年, 閏月Flag, 旧暦月, 旧暦日]
569
+ #=========================================================================
570
+ def compute_oc(jd = @jd_jst)
571
+ jd -= 0.5
572
+ tm0 = jd
573
+ # 二分二至,中気の時刻・黄経用配列宣言
574
+ chu = Array.new(4).map { Array.new(2, 0) }
575
+ # 朔用配列宣言
576
+ saku = Array.new(5, 0)
577
+ # 朔日用配列宣言
578
+ m = Array.new(5).map { Array.new(3, 0) }
579
+ # 旧暦用配列宣言
580
+ kyureki = Array.new(4, 0)
581
+
582
+ # 計算対象の直前にあたる二分二至の時刻を計算
583
+ # chu[0][0] : 二分二至の時刻
584
+ # chu[0][1] : その時の太陽黄経
585
+ chu[0] = compute_last_nc(tm0, 90)
586
+ # 中気の時刻を計算 ( 3回計算する )
587
+ # chu[i][0] : 中気の時刻
588
+ # chu[i][1] : その時の太陽黄経
589
+ 1.upto(3) do |i|
590
+ chu[i] = compute_last_nc(chu[i - 1][0] + 32, 30)
591
+ end
592
+ # 計算対象の直前にあたる二分二至の直前の朔の時刻を求める
593
+ saku[0] = compute_saku(chu[0][0])
594
+ # 朔の時刻を求める
595
+ 1.upto(4) do |i|
596
+ tm = saku[i-1] + 30
597
+ saku[i] = compute_saku(tm)
598
+ # 前と同じ時刻を計算した場合( 両者の差が26日以内 )には、初期値を
599
+ # +33日にして再実行させる。
600
+ if (saku[i-1].truncate - saku[i].truncate).abs <= 26
601
+ saku[i] = compute_saku(saku[i-1] + 35)
602
+ end
603
+ end
604
+ # saku[1]が二分二至の時刻以前になってしまった場合には、朔をさかのぼり過ぎ
605
+ # たと考えて、朔の時刻を繰り下げて修正する。
606
+ # その際、計算もれ(saku[4])になっている部分を補うため、朔の時刻を計算
607
+ # する。(近日点通過の近辺で朔があると起こる事があるようだ...?)
608
+ if saku[1].truncate <= chu[0][0].truncate
609
+ 0.upto(3) { |i| saku[i] = saku[i+1] }
610
+ saku[4] = compute_saku(saku[3] + 35)
611
+ # saku[0]が二分二至の時刻以後になってしまった場合には、朔をさかのぼり足
612
+ # りないと見て、朔の時刻を繰り上げて修正する。
613
+ # その際、計算もれ(saku[0])になっている部分を補うため、朔の時刻を計算
614
+ # する。(春分点の近辺で朔があると起こる事があるようだ...?)
615
+ elsif saku[0].truncate > chu[0][0].truncate
616
+ 4.downto(1) { |i| saku[i] = saku[i-1] }
617
+ saku[0] = compute_saku(saku[0] - 27)
618
+ end
619
+ # 閏月検索Flagセット
620
+ # (節月で4ヶ月の間に朔が5回あると、閏月がある可能性がある。)
621
+ # leap=0:平月 leap=1:閏月
622
+ leap = 0
623
+ leap = 1 if saku[4].truncate <= chu[3][0].truncate
624
+ # 朔日行列の作成
625
+ # m[i][0] ... 月名 ( 1:正月 2:2月 3:3月 .... )
626
+ # m[i][1] ... 閏フラグ ( 0:平月 1:閏月 )
627
+ # m[i][2] ... 朔日のjd
628
+ m[0][0] = (chu[0][1] / 30.0).truncate + 2
629
+ m[0][0] -= 12 if m[0][0] > 12
630
+ m[0][2] = saku[0].truncate
631
+ m[0][1] = 0
632
+ 1.upto(4) do |i|
633
+ if leap == 1 && i != 1
634
+ if chu[i-1][0].truncate <= saku[i-1].truncate ||
635
+ chu[i-1][0].truncate >= saku[i].truncate
636
+ m[i-1][0] = m[i-2][0]
637
+ m[i-1][1] = 1
638
+ m[i-1][2] = saku[i-1].truncate
639
+ leap = 0
640
+ end
641
+ end
642
+ m[i][0] = m[i-1][0] + 1
643
+ m[i][0] -= 12 if m[i][0] > 12
644
+ m[i][2] = saku[i].truncate
645
+ m[i][1] = 0
646
+ end
647
+ # 朔日行列から旧暦を求める。
648
+ state, index = 0, 0
649
+ 0.upto(4) do |i|
650
+ index = i
651
+ if tm0.truncate < m[i][2].truncate
652
+ state = 1
653
+ break
654
+ elsif tm0.truncate == m[i][2].truncate
655
+ state = 2
656
+ break
657
+ end
658
+ end
659
+ index -= 1 if state == 1
660
+ kyureki[1] = m[index][1]
661
+ kyureki[2] = m[index][0]
662
+ kyureki[3] = tm0.truncate - m[index][2].truncate + 1
663
+ # 旧暦年の計算
664
+ # (旧暦月が10以上でかつ新暦月より大きい場合には、
665
+ # まだ年を越していないはず...)
666
+ a = jd2ymd(tm0)
667
+ kyureki[0] = a[0]
668
+ kyureki[0] -= 1 if kyureki[2] > 9 && kyureki[2] > a[1]
669
+ return kyureki
670
+ end
671
+
672
+ #=========================================================================
673
+ # Gregorian Calendar -> Julian Day
674
+ #
675
+ # * フリーゲルの公式を使用する
676
+ # [ JD ] = int( 365.25 × year )
677
+ # + int( year / 400 )
678
+ # - int( year / 100 )
679
+ # + int( 30.59 ( month - 2 ) )
680
+ # + day
681
+ # + 1721088
682
+ # ※上記の int( x ) は厳密には、x を超えない最大の整数
683
+ # ( ちなみに、[ 準JD ]を求めるなら + 1721088.5 が - 678912 となる )
684
+ #
685
+ # @param: year
686
+ # @param: month
687
+ # @param: day
688
+ # @param: hour
689
+ # @param: minute
690
+ # @param: second
691
+ # @return: jd ( ユリウス日 )
692
+ #=========================================================================
693
+ def gc2jd(year, month, day, hour = 0, min = 0, sec = 0)
694
+ # 1月,2月は前年の13月,14月とする
695
+ if month < 3
696
+ year -= 1
697
+ month += 12
698
+ end
699
+ # 日付(整数)部分計算
700
+ jd = (365.25 * year).truncate
701
+ jd += (year / 400.0).truncate
702
+ jd -= (year / 100.0).truncate
703
+ jd += (30.59 * (month - 2)).truncate
704
+ jd += day
705
+ jd += 1721088.125
706
+ # 時間(小数)部分計算
707
+ t = sec / 3600.0
708
+ t += min / 60.0
709
+ t += hour
710
+ t = t / 24.0
711
+ return jd + t
712
+ end
713
+
714
+ #=========================================================================
715
+ # Julian Day -> UT
716
+ #
717
+ # @param: jd (ユリウス通日)
718
+ # @return: [year, month, day, hour, minute, second]
719
+ #=========================================================================
720
+ def jd2ymd(jd)
721
+ ut = Array.new(6, 0)
722
+ x0 = (jd + 68570).truncate
723
+ x1 = (x0 / 36524.25).truncate
724
+ x2 = x0 - (36524.25 * x1 + 0.75).truncate
725
+ x3 = ((x2 + 1) / 365.2425).truncate
726
+ x4 = x2 - (365.25 * x3).truncate + 31
727
+ x5 = (x4.truncate / 30.59).truncate
728
+ x6 = (x5.truncate / 11.0).truncate
729
+ ut[2] = x4 - (30.59 * x5).truncate
730
+ ut[1] = x5 - 12 * x6 + 2
731
+ ut[0] = 100 * (x1 - 49) + x3 + x6
732
+ # 2月30日の補正
733
+ if ut[1]==2 && ut[2] > 28
734
+ if ut[0] % 100 == 0 && ut[0] % 400 == 0
735
+ ut[2] = 29
736
+ elsif ut[0] % 4 == 0
737
+ ut[2] = 29
738
+ else
739
+ ut[2] = 28
740
+ end
741
+ end
742
+ tm = 86400 * (jd - jd.truncate)
743
+ ut[3] = (tm / 3600.0).truncate
744
+ ut[4] = ((tm - 3600 * ut[3]) / 60.0).truncate
745
+ ut[5] = (tm - 3600 * ut[3] - 60 * ut[4]).truncate
746
+ return ut
747
+ end
748
+
749
+ #=========================================================================
750
+ # 直前二分二至・中気時刻の計算
751
+ #
752
+ # @param: jd (ユリウス日)
753
+ # @param: kbn (90: 二分二至, 30: 中気)
754
+ # @return: [二分二至・中気の時刻, その時の黄経]
755
+ #=========================================================================
756
+ def compute_last_nc(jd, kbn)
757
+ jd -= 0.5
758
+ # 時刻引数を分解
759
+ tm1 = jd.truncate # 整数部分
760
+ tm2 = jd - tm1 # 小数部分
761
+ tm2 -= Const::JST_D
762
+
763
+ # 直前の二分二至の黄経 λsun0 を求める
764
+ rm_sun = compute_lambda_sun(jd + 0.5)
765
+ rm_sun0 = kbn * (rm_sun / kbn.to_f).truncate
766
+
767
+ # 繰り返し計算によって直前の二分二至の時刻を計算する
768
+ # (誤差が±1.0 sec以内になったら打ち切る。)
769
+ delta_t1 = 0 ; delta_t2 = 1
770
+ while (delta_t1 + delta_t2).abs > (1.0 / 86400.0)
771
+ # λsun を計算
772
+ t = tm1 + tm2 + Const::JST_D + 0.5
773
+ rm_sun = compute_lambda_sun(t)
774
+
775
+ # 黄経差 Δλ=λsun -λsun0
776
+ delta_rm = rm_sun - rm_sun0
777
+
778
+ # Δλの引き込み範囲(±180°)を逸脱した場合には、補正を行う
779
+ case
780
+ when delta_rm > 180; delta_rm -= 360
781
+ when delta_rm < -180; delta_rm += 360
782
+ end
783
+
784
+ # 時刻引数の補正値 Δt
785
+ delta_t1 = (delta_rm * 365.2 / 360.0).truncate
786
+ delta_t2 = delta_rm * 365.2 / 360.0 - delta_t1
787
+
788
+ # 時刻引数の補正
789
+ tm1 = tm1 - delta_t1
790
+ tm2 = tm2 - delta_t2
791
+ if tm2 < 0
792
+ tm2 += 1
793
+ tm1 -= 1
794
+ end
795
+ end
796
+
797
+ # nibun_chu[0] : 時刻引数を合成、DT ==> JST 変換を行い、戻り値とする
798
+ # ( 補正時刻=0.0sec と仮定して計算 )
799
+ # nibun_chu[1] : 黄経
800
+ nibun_chu = Array.new(2, 0)
801
+ nibun_chu[0] = tm2 + 9 / 24.0
802
+ nibun_chu[0] += tm1
803
+ nibun_chu[1] = rm_sun0
804
+ return nibun_chu
805
+ end
806
+
807
+ #=========================================================================
808
+ # 角度の正規化
809
+ #
810
+ # @param: angle
811
+ # @return: angle
812
+ #=========================================================================
813
+ def norm_angle(angle)
814
+ if angle < 0
815
+ angle1 = angle * (-1)
816
+ angle2 = (angle1 / 360.0).truncate
817
+ angle1 -= 360 * angle2
818
+ angle1 = 360 - angle1
819
+ else
820
+ angle1 = (angle / 360.0).truncate
821
+ angle1 = angle - 360.0 * angle1
822
+ end
823
+ return angle1
824
+ end
825
+
826
+ #=========================================================================
827
+ # 直近の朔の時刻(JST)の計算
828
+ #
829
+ # @param: jd (ユリウス日)
830
+ # @return: saku (直前の朔の時刻)
831
+ #=========================================================================
832
+ def compute_saku(jd = @jd_jst)
833
+ jd -= 0.5
834
+ lc = 1
835
+
836
+ # 時刻引数を分解する
837
+ tm1 = jd.truncate
838
+ tm2 = jd - tm1
839
+ tm2 -= Const::JST_D
840
+
841
+ # 繰り返し計算によって朔の時刻を計算する
842
+ # (誤差が±1.0 sec以内になったら打ち切る。)
843
+ delta_t1 = 0 ; delta_t2 = 1
844
+ while (delta_t1 + delta_t2).abs > (1.0 / 86400.0)
845
+ # 太陽の黄経λsun ,月の黄経λmoon を計算
846
+ t = tm1 + tm2 + Const::JST_D + 0.5
847
+ rm_sun = compute_lambda_sun(t)
848
+ rm_moon = compute_lambda_moon(t)
849
+ # 月と太陽の黄経差Δλ
850
+ # Δλ=λmoon-λsun
851
+ delta_rm = rm_moon - rm_sun
852
+ # ループの1回目 ( lc = 1 ) で delta_rm < 0.0 の場合には引き込み範囲に
853
+ # 入るように補正する
854
+ if lc == 1 && delta_rm < 0
855
+ delta_rm = norm_angle(delta_rm)
856
+ # 春分の近くで朔がある場合 ( 0 ≦λsun≦ 20 ) で、月の黄経λmoon≧300 の
857
+ # 場合には、Δλ= 360.0 - Δλ と計算して補正する
858
+ elsif rm_sun >= 0 && rm_sun <= 20 && rm_moon >= 300
859
+ delta_rm = norm_angle(delta_rm)
860
+ delta_rm = 360 - delta_rm
861
+ # Δλの引き込み範囲 ( ±40° ) を逸脱した場合には、補正を行う
862
+ elsif delta_rm.abs > 40.0
863
+ delta_rm = norm_angle(delta_rm)
864
+ end
865
+ # 時刻引数の補正値 Δt
866
+ delta_t1 = (delta_rm * 29.530589 / 360.0).truncate
867
+ delta_t2 = delta_rm * 29.530589 / 360.0 - delta_t1
868
+ # 時刻引数の補正
869
+ tm1 = tm1 - delta_t1
870
+ tm2 = tm2 - delta_t2
871
+ if tm2 < 0
872
+ tm2 += 1
873
+ tm1 -= 1
874
+ end
875
+ # ループ回数が15回になったら、初期値 tm を tm-26 とする。
876
+ if lc == 15 && (delta_t1 + delta_t2).abs > (1.0 / 86400.0)
877
+ tm1 = (jd - 26).truncate
878
+ tm2 = 0
879
+ # 初期値を補正したにも関わらず、振動を続ける場合には初期値を答えとして
880
+ # 返して強制的にループを抜け出して異常終了させる。
881
+ elsif lc > 30 && (delta_t1+delta_t2).abs > (1.0 / 86400.0)
882
+ tm1 = jd
883
+ tm2 = 0
884
+ break
885
+ end
886
+ lc += 1
887
+ end
888
+ # 時刻引数を合成、DT ==> JST 変換を行い、戻り値とする
889
+ # (補正時刻=0.0sec と仮定して計算)
890
+ return tm2 + tm1 + 9 / 24.0
891
+ end
892
+
893
+ #=========================================================================
894
+ # ΔT の計算
895
+ #
896
+ # * 1972-01-01 以降、うるう秒挿入済みの年+αまでは、以下で算出
897
+ # TT - UTC = ΔT + DUT1 = TAI + 32.184 - UTC = ΔAT + 32.184
898
+ # [うるう秒実施日一覧](http://jjy.nict.go.jp/QandA/data/leapsec.html)
899
+ #
900
+ # @param: year
901
+ # @param: month
902
+ # @param: day
903
+ # @return: dt
904
+ #=========================================================================
905
+ def compute_dt(year = @year, month = @month, day = @day)
906
+ ymd = sprintf("%04d-%02d-%02d", year, month, day)
907
+ case
908
+ when year < -500
909
+ t = (year-1820) / 100.0
910
+ dt = -20 + 32 * t ** 2
911
+ when -500 <= year && year < 500
912
+ t = year / 100.0
913
+ dt = 10583.6
914
+ (-1014.41 + \
915
+ ( 33.78311 + \
916
+ ( -5.952053 + \
917
+ ( -0.1798452 + \
918
+ ( 0.022174192 + \
919
+ ( 0.0090316521) \
920
+ * t) * t) * t) * t) * t) * t
921
+ when 500 <= year && year < 1600
922
+ t = (year - 1000) / 100.0
923
+ dt = 1574.2 + \
924
+ (-556.01 + \
925
+ ( 71.23472 + \
926
+ ( 0.319781 + \
927
+ ( -0.8503463 + \
928
+ ( -0.005050998 + \
929
+ ( 0.0083572073) \
930
+ * t) * t) * t) * t) * t) * t
931
+ when 1600 <= year && year < 1700
932
+ t = year - 1600
933
+ dt = 120 + \
934
+ ( -0.9808 + \
935
+ ( -0.01532 + \
936
+ ( 1.0 / 7129.0) \
937
+ * t) * t) * t
938
+ when 1700 <= year && year < 1800
939
+ t = year - 1700
940
+ dt = 8.83 + \
941
+ ( 0.1603 + \
942
+ (-0.0059285 + \
943
+ ( 0.00013336 + \
944
+ (-1.0 / 1174000.0) \
945
+ * t) * t) * t) * t
946
+ when 1800 <= year && year < 1860
947
+ t = year - 1800
948
+ dt = 13.72 + \
949
+ (-0.332447 + \
950
+ ( 0.0068612 + \
951
+ ( 0.0041116 + \
952
+ (-0.00037436 + \
953
+ ( 0.0000121272 + \
954
+ (-0.0000001699 + \
955
+ ( 0.000000000875) \
956
+ * t) * t) * t) * t) * t) * t) * t
957
+ when 1860 <= year && year < 1900
958
+ t = year - 1860
959
+ dt = 7.62 + \
960
+ ( 0.5737 + \
961
+ (-0.251754 + \
962
+ ( 0.01680668 + \
963
+ (-0.0004473624 + \
964
+ ( 1.0 / 233174.0) \
965
+ * t) * t) * t) * t) * t
966
+ when 1900 <= year && year < 1920
967
+ t = year - 1900
968
+ dt = -2.79 + \
969
+ ( 1.494119 + \
970
+ (-0.0598939 + \
971
+ ( 0.0061966 + \
972
+ (-0.000197 ) \
973
+ * t) * t) * t) * t
974
+ when 1920 <= year && year < 1941
975
+ t = year - 1920
976
+ dt = 21.20 + \
977
+ ( 0.84493 + \
978
+ (-0.076100 + \
979
+ ( 0.0020936) \
980
+ * t) * t) * t
981
+ when 1941 <= year && year < 1961
982
+ t = year - 1950
983
+ dt = 29.07 + \
984
+ ( 0.407 + \
985
+ (-1 / 233.0 + \
986
+ ( 1 / 2547.0) \
987
+ * t) * t) * t
988
+ when 1961 <= year && year < 1986
989
+ case
990
+ when ymd < sprintf("%04d-%02d-%02d", 1972, 1, 1)
991
+ t = year - 1975
992
+ dt = 45.45 + \
993
+ ( 1.067 + \
994
+ (-1 / 260.0 + \
995
+ (-1 / 718.0) \
996
+ * t) * t) * t
997
+ when ymd < sprintf("%04d-%02d-%02d", 1972, 7, 1)
998
+ dt = 32.184 + 10
999
+ when ymd < sprintf("%04d-%02d-%02d", 1973, 1, 1)
1000
+ dt = 32.184 + 11
1001
+ when ymd < sprintf("%04d-%02d-%02d", 1974, 1, 1)
1002
+ dt = 32.184 + 12
1003
+ when ymd < sprintf("%04d-%02d-%02d", 1975, 1, 1)
1004
+ dt = 32.184 + 13
1005
+ when ymd < sprintf("%04d-%02d-%02d", 1976, 1, 1)
1006
+ dt = 32.184 + 14
1007
+ when ymd < sprintf("%04d-%02d-%02d", 1977, 1, 1)
1008
+ dt = 32.184 + 15
1009
+ when ymd < sprintf("%04d-%02d-%02d", 1978, 1, 1)
1010
+ dt = 32.184 + 16
1011
+ when ymd < sprintf("%04d-%02d-%02d", 1979, 1, 1)
1012
+ dt = 32.184 + 17
1013
+ when ymd < sprintf("%04d-%02d-%02d", 1980, 1, 1)
1014
+ dt = 32.184 + 18
1015
+ when ymd < sprintf("%04d-%02d-%02d", 1981, 7, 1)
1016
+ dt = 32.184 + 19
1017
+ when ymd < sprintf("%04d-%02d-%02d", 1982, 7, 1)
1018
+ dt = 32.184 + 20
1019
+ when ymd < sprintf("%04d-%02d-%02d", 1983, 7, 1)
1020
+ dt = 32.184 + 21
1021
+ when ymd < sprintf("%04d-%02d-%02d", 1985, 7, 1)
1022
+ dt = 32.184 + 22
1023
+ when ymd < sprintf("%04d-%02d-%02d", 1988, 1, 1)
1024
+ dt = 32.184 + 23
1025
+ end
1026
+ when 1986 <= year && year < 2005
1027
+ # t = year - 2000
1028
+ #dt = 63.86 + \
1029
+ # ( 0.3345 + \
1030
+ # (-0.060374 + \
1031
+ # ( 0.0017275 + \
1032
+ # ( 0.000651814 + \
1033
+ # ( 0.00002373599) \
1034
+ # * t) * t) * t) * t) * t
1035
+ case
1036
+ when ymd < sprintf("%04d-%02d-%02d", 1988, 1, 1)
1037
+ dt = 32.184 + 23
1038
+ when ymd < sprintf("%04d-%02d-%02d", 1990, 1, 1)
1039
+ dt = 32.184 + 24
1040
+ when ymd < sprintf("%04d-%02d-%02d", 1991, 1, 1)
1041
+ dt = 32.184 + 25
1042
+ when ymd < sprintf("%04d-%02d-%02d", 1992, 7, 1)
1043
+ dt = 32.184 + 26
1044
+ when ymd < sprintf("%04d-%02d-%02d", 1993, 7, 1)
1045
+ dt = 32.184 + 27
1046
+ when ymd < sprintf("%04d-%02d-%02d", 1994, 7, 1)
1047
+ dt = 32.184 + 28
1048
+ when ymd < sprintf("%04d-%02d-%02d", 1996, 1, 1)
1049
+ dt = 32.184 + 29
1050
+ when ymd < sprintf("%04d-%02d-%02d", 1997, 7, 1)
1051
+ dt = 32.184 + 30
1052
+ when ymd < sprintf("%04d-%02d-%02d", 1999, 1, 1)
1053
+ dt = 32.184 + 31
1054
+ when ymd < sprintf("%04d-%02d-%02d", 2006, 1, 1)
1055
+ dt = 32.184 + 32
1056
+ end
1057
+ when 2005 <= year && year < 2050
1058
+ case
1059
+ when ymd < sprintf("%04d-%02d-%02d", 2006, 1, 1)
1060
+ dt = 32.184 + 32
1061
+ when ymd < sprintf("%04d-%02d-%02d", 2009, 1, 1)
1062
+ dt = 32.184 + 33
1063
+ when ymd < sprintf("%04d-%02d-%02d", 2012, 7, 1)
1064
+ dt = 32.184 + 34
1065
+ when ymd < sprintf("%04d-%02d-%02d", 2015, 7, 1)
1066
+ dt = 32.184 + 35
1067
+ when ymd < sprintf("%04d-%02d-%02d", 2017, 7, 1) # <= 第27回うるう秒実施までの暫定措置
1068
+ dt = 32.184 + 36
1069
+ else
1070
+ t = year - 2000
1071
+ dt = 62.92 + \
1072
+ ( 0.32217 + \
1073
+ ( 0.005589) \
1074
+ * t) * t
1075
+ end
1076
+ when 2050 <= year && year <= 2150
1077
+ dt = -20 \
1078
+ + 32 * ((year - 1820) / 100.0) ** 2
1079
+ - 0.5628 * (2150 - year)
1080
+ when 2150 < year
1081
+ t = (year - 1820) / 100.0
1082
+ dt = -20 + 32 * t ** 2
1083
+ end
1084
+ return dt
1085
+ end
1086
+
1087
+ #=========================================================================
1088
+ # 2000年1月1日力学時正午からの経過日数の計算
1089
+ #
1090
+ # @param: year
1091
+ # @param: month
1092
+ # @param: day
1093
+ # @return: dp (= day progress)
1094
+ #=========================================================================
1095
+ def gc2j2000(year = @year, month = @month, day = @day)
1096
+ year -= 2000
1097
+ # 1月,2月は前年の13月,14月とする
1098
+ if month < 3
1099
+ year -= 1
1100
+ month += 12
1101
+ end
1102
+ dp = 365 * year + 30 * month + day - 33.5 - Const::JST_D
1103
+ dp += (3 * (month + 1) / 5.0).truncate
1104
+ dp += (year / 4.0).truncate
1105
+ return dp
1106
+ end
1107
+
1108
+ #=========================================================================
1109
+ # 六曜の計算
1110
+ #
1111
+ # * 旧暦一日の六曜
1112
+ # 1・7月 : 先勝
1113
+ # 2・8月 : 友引
1114
+ # 3・9月 : 先負
1115
+ # 4・10月 : 仏滅
1116
+ # 5・11月 : 大安
1117
+ # 6・12月 : 赤口
1118
+ # と決まっていて、あとは月末まで順番通り。
1119
+ # よって、月と日をたした数を6で割った余りによって六曜を決定することができます。
1120
+ # ( 旧暦の月 + 旧暦の日 ) ÷ 6 = ? … 余り
1121
+ # 余り 0 : 大安
1122
+ # 1 : 赤口
1123
+ # 2 : 先勝
1124
+ # 3 : 友引
1125
+ # 4 : 先負
1126
+ # 5 : 仏滅
1127
+ #
1128
+ # @param: oc_month (旧暦の月)
1129
+ # @param: oc_day (旧暦の日)
1130
+ # @return: rokuyo (漢字2文字)
1131
+ #=========================================================================
1132
+ def compute_rokuyo(oc_month = @oc_month, oc_day = @oc_day)
1133
+ return Const::ROKUYO[(oc_month + oc_day) % 6]
1134
+ end
1135
+ end
1136
+ end
1137
+