zakuro 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/zakuro/calculation/cycle/abstract_remainder.rb +12 -0
  3. data/lib/zakuro/calculation/range/full_range.rb +1 -1
  4. data/lib/zakuro/version.rb +1 -1
  5. data/lib/zakuro/version/senmyou/const/number.rb +51 -0
  6. data/lib/zakuro/version/senmyou/const/remainder.rb +43 -0
  7. data/lib/zakuro/version/senmyou/cycle/remainder.rb +4 -6
  8. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +35 -54
  9. data/lib/zakuro/version/senmyou/range/annual_range.rb +9 -65
  10. data/lib/zakuro/version/senmyou/stella/lunar/adjustment.rb +237 -0
  11. data/lib/zakuro/version/senmyou/stella/lunar/localization.rb +45 -0
  12. data/lib/zakuro/version/senmyou/stella/lunar/location.rb +108 -0
  13. data/lib/zakuro/version/senmyou/stella/lunar/value.rb +89 -0
  14. data/lib/zakuro/version/senmyou/stella/origin/average_november.rb +34 -0
  15. data/lib/zakuro/version/senmyou/stella/origin/lunar_age.rb +62 -0
  16. data/lib/zakuro/version/senmyou/stella/origin/winter_solstice.rb +55 -0
  17. data/lib/zakuro/version/senmyou/stella/solar/adjustment.rb +93 -0
  18. data/lib/zakuro/version/senmyou/stella/solar/average.rb +175 -0
  19. data/lib/zakuro/version/senmyou/stella/solar/interval.rb +103 -0
  20. data/lib/zakuro/version/senmyou/stella/solar/location.rb +164 -0
  21. data/lib/zakuro/version/senmyou/stella/solar/value.rb +138 -0
  22. metadata +20 -11
  23. data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +0 -332
  24. data/lib/zakuro/version/senmyou/stella/solar_average.rb +0 -169
  25. data/lib/zakuro/version/senmyou/stella/solar_location.rb +0 -213
  26. data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +0 -213
  27. data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +0 -106
@@ -1,169 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # :nodoc:
4
- module Zakuro
5
- # :nodoc:
6
- module Senmyou
7
- #
8
- # SolarAverage 常気(太陽軌道平均)
9
- #
10
- class SolarAverage
11
- # @return [Remainder] 気策(24分の1年)
12
- SOLAR_TERM_AVERAGE = Cycle::Remainder.new(day: 15, minute: 1835, second: 5)
13
-
14
- #
15
- # 初期化
16
- #
17
- # @param [Integer] western_year 西暦年
18
- #
19
- def initialize(western_year:)
20
- @solar_term = SolarAverage.first_solar_term(western_year: western_year)
21
- end
22
-
23
- #
24
- # 冬至から数えた1年データの月ごとに二十四節気を割り当てる
25
- #
26
- # @param [Array<Month>] annual_range 1年データ
27
- #
28
- # @return [Array<Month>] 1年データ
29
- #
30
- def set(annual_range:)
31
- # 次月と比較しながら当月の二十四節気を決める
32
- # NOTE: 最後の月は処理できない(=計算外の余分な月が最後に必要である)
33
- annual_range.each_cons(2) do |(current_month, next_month)|
34
- set_solar_term(
35
- current_month: current_month,
36
- next_month: next_month
37
- )
38
- end
39
-
40
- annual_range
41
- end
42
-
43
- #
44
- # 計算開始する二十四節気を求める
45
- #
46
- # @param [Integer] western_year 西暦年
47
- #
48
- # @return [SolarTerm] 二十四節気
49
- #
50
- def self.first_solar_term(western_year:)
51
- # 天正冬至
52
- winter_solstice = WinterSolstice.calc(western_year: western_year)
53
-
54
- # 二十四節気(冬至)
55
- solar_term = Cycle::SolarTerm.new(index: 0, remainder: winter_solstice)
56
-
57
- first_solar_term_index = SolarAverage.calc_fist_solar_term_index(western_year: western_year)
58
-
59
- # 対象の二十四節気まで戻す
60
- solar_term.prev_by_index(first_solar_term_index)
61
-
62
- solar_term
63
- end
64
-
65
- #
66
- # 計算開始する二十四節気番号を求める
67
- #
68
- # * 前提として入定気は冬至の手前にある
69
- # * 例えば、定気が大雪であれば入定気は大雪の範囲内にある
70
- # * 入定気は、定気の開始位置に重複しない限り、常に定気より後にある
71
- # * 基本的に定気の一つ前から起算すれば、当時から求めた11月(閏10/閏11月)に二十四節気を割り当てられる
72
- #
73
- # @param [Integer] western_year 西暦年
74
- #
75
- # @return [Integer] 二十四節気番号
76
- #
77
- def self.calc_fist_solar_term_index(western_year:)
78
- # 天正閏余
79
- winter_solstice_age = \
80
- WinterSolstice.calc_moon_age(western_year: western_year)
81
-
82
- # 入定気を求める
83
- solar_location = SolarLocation.get(
84
- solar_term: Cycle::SolarTerm.new(remainder: winter_solstice_age)
85
- )
86
-
87
- solar_term_index = solar_location.index
88
-
89
- # 入定気の一つ後の二十四節気まで戻す(ただし11月経朔が二十四節気上にある場合は戻さない)
90
- solar_term_index += 1 unless solar_location.remainder == Cycle::Remainder.new(total: 0)
91
-
92
- solar_term_index
93
- end
94
-
95
- # :reek:TooManyStatements { max_statements: 7 }
96
-
97
- #
98
- # 月内(当月朔日から当月末日(来月朔日の前日)の間)に二十四節気があるか
99
- # @note 大余60で一巡するため 以下2パターンがある
100
- # * current_month <= next_month : (二十四節気) >= current_month && (二十四節気) < next_month
101
- # * current_month > next_month : (二十四節気) >= current_month || (二十四節気) < next_month
102
- #
103
- # @param [Remainder] solar_term 二十四節気
104
- # @param [Remainder] current_month 月初
105
- # @param [Remainder] next_month 月末
106
- #
107
- # @return [True] 対象の二十四節気がある
108
- # @return [False] 対象の二十四節気がない
109
- #
110
- def self.in_solar_term?(solar_term:, current_month:, next_month:)
111
- # 大余で比較する
112
- target_time = solar_term.day
113
- current_month_time = current_month.day
114
- next_month_time = next_month.day
115
- current_month_over = (target_time >= current_month_time)
116
- next_month_under = (target_time < next_month_time)
117
-
118
- return current_month_over && next_month_under if current_month_time <= next_month_time
119
-
120
- current_month_over || next_month_under
121
- end
122
-
123
- private
124
-
125
- # :reek:TooManyStatements { max_statements: 8 }
126
-
127
- #
128
- # 二十四節気を設定する
129
- #
130
- # @param [Month] current_month 当月
131
- # @param [Month] next_month 次月
132
- #
133
- def set_solar_term(current_month:, next_month:)
134
- # 安全策として無限ループは回避する
135
- # * 最大試行回数:4回(設定なし => 設定あり => 設定あり => 設定なし)
136
- # * 閏月は1回しか設定しない
137
- # * 最大2回設定する(中気・節気)
138
- (0..3).each do |_index|
139
- in_range = SolarAverage.in_solar_term?(
140
- solar_term: @solar_term.remainder, current_month: current_month.remainder,
141
- next_month: next_month.remainder
142
- )
143
-
144
- # 範囲外
145
- unless in_range
146
- # 1つ以上設定されていれば切り上げる(一つ飛ばしで二十四節気を設定することはない)
147
- break unless current_month.empty_solar_term?
148
-
149
- next_solar_term
150
- next
151
- end
152
-
153
- current_month.add_term(term: @solar_term.clone)
154
- next_solar_term
155
-
156
- # 宣明暦は最大2つまで
157
- break if current_month.solar_term_size == 2
158
- end
159
- end
160
-
161
- #
162
- # 次の二十四節気に移る
163
- #
164
- def next_solar_term
165
- @solar_term.next_term!
166
- end
167
- end
168
- end
169
- end
@@ -1,213 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # :nodoc:
4
- module Zakuro
5
- # :nodoc:
6
- module Senmyou
7
- #
8
- # SolarLocation 入定気演算
9
- #
10
- # 入定気とは、太陽がどの二十四節気に属するか、またその二十四節気の開始点からどれだけ離れているかを示す
11
- #
12
- module SolarLocation
13
- #
14
- # Interval 入気定日加減数(二十四節気の間隔)
15
- #
16
- module Interval
17
- # @return [Hash<Symbol, Remainder>] 一覧
18
- LIST = {
19
- # 冬至(とうじ)・大雪(たいせつ)
20
- touji: Cycle::Remainder.new(day: 14, minute: 4235, second: 5),
21
- taisetsu: Cycle::Remainder.new(day: 14, minute: 4235, second: 5),
22
- # 小寒(しょうかん)・小雪(しょうせつ)
23
- shoukan: Cycle::Remainder.new(day: 14, minute: 5235, second: 5),
24
- shousetsu: Cycle::Remainder.new(day: 14, minute: 5235, second: 5),
25
- # 大寒(だいかん)・立冬(りっとう)
26
- daikan: Cycle::Remainder.new(day: 14, minute: 6235, second: 5),
27
- rittou: Cycle::Remainder.new(day: 14, minute: 6235, second: 5),
28
- # 立春(りっしゅん)・霜降(そうこう)
29
- risshun: Cycle::Remainder.new(day: 14, minute: 7235, second: 5),
30
- soukou: Cycle::Remainder.new(day: 14, minute: 7235, second: 5),
31
- # 雨水(うすい)・寒露(かんろ)
32
- usui: Cycle::Remainder.new(day: 15, minute: 35, second: 5),
33
- kanro: Cycle::Remainder.new(day: 15, minute: 35, second: 5),
34
- # 啓蟄(けいちつ)・秋分(しゅうぶん)
35
- keichitsu: Cycle::Remainder.new(day: 15, minute: 1235, second: 5),
36
- shuubun: Cycle::Remainder.new(day: 15, minute: 1235, second: 5),
37
- # 春分(しゅんぶん)・白露(はくろ)
38
- shunbun: Cycle::Remainder.new(day: 15, minute: 2435, second: 5),
39
- hakuro: Cycle::Remainder.new(day: 15, minute: 2435, second: 5),
40
- # 清明(せいめい)・処暑(しょしょ)
41
- seimei: Cycle::Remainder.new(day: 15, minute: 3635, second: 5),
42
- shosho: Cycle::Remainder.new(day: 15, minute: 3635, second: 5),
43
- # 穀雨(こくう)・立秋(りっしゅう)
44
- kokuu: Cycle::Remainder.new(day: 15, minute: 4835, second: 5),
45
- risshuu: Cycle::Remainder.new(day: 15, minute: 4835, second: 5),
46
- # 立夏(りっか)・大暑(たいしょ)
47
- rikka: Cycle::Remainder.new(day: 15, minute: 5835, second: 5),
48
- taisho: Cycle::Remainder.new(day: 15, minute: 5835, second: 5),
49
- # 小満(しょうまん)・小暑(しょうしょ)
50
- shouman: Cycle::Remainder.new(day: 15, minute: 6835, second: 5),
51
- shousho: Cycle::Remainder.new(day: 15, minute: 6835, second: 5),
52
- # 芒種(ぼうしゅ)・夏至(げし)
53
- boushu: Cycle::Remainder.new(day: 15, minute: 7835, second: 5),
54
- geshi: Cycle::Remainder.new(day: 15, minute: 7835, second: 5)
55
- }.freeze
56
-
57
- # @return [Array<Remainder>] 索引
58
- INDEXES = [
59
- LIST[:touji], # 0
60
- LIST[:shoukan], # 1
61
- LIST[:daikan], # 2
62
- LIST[:risshun], # 3
63
- LIST[:usui], # 4
64
- LIST[:keichitsu], # 5
65
- LIST[:shunbun], # 6
66
- LIST[:seimei], # 7
67
- LIST[:kokuu], # 8
68
- LIST[:rikka], # 9
69
- LIST[:shouman], # 10
70
- LIST[:boushu], # 11
71
- LIST[:geshi], # 12
72
- LIST[:shousho], # 13
73
- LIST[:taisho], # 14
74
- LIST[:risshuu], # 15
75
- LIST[:shosho], # 16
76
- LIST[:hakuro], # 17
77
- LIST[:shuubun], # 18
78
- LIST[:kanro], # 19
79
- LIST[:soukou], # 20
80
- LIST[:rittou], # 21
81
- LIST[:shousetsu], # 22
82
- LIST[:taisetsu] # 23
83
- ].freeze
84
- end
85
-
86
- #
87
- # 入定気を計算する
88
- #
89
- # * 定気(index)の指定がない場合は、11月の入定気を求める
90
- # * 定気(index)の指定がある場合は、大余小余から適切な入定気を再計算する
91
- #
92
- # @param [SolarTerm] solar_term 入定気
93
- #
94
- # @return [SolarTerm] 入定気
95
- #
96
- def self.get(solar_term:)
97
- if solar_term.invalid?
98
- return calc_first_solar_term(
99
- winter_solstice_age: solar_term.remainder
100
- )
101
- end
102
-
103
- calc_next_solar_term_recursively(
104
- solar_term: solar_term
105
- )
106
- end
107
-
108
- # :reek:TooManyStatements { max_statements: 7 }
109
-
110
- #
111
- # 入定気(定気の開始点からの日時)と属する定気を計算する
112
- #
113
- # @param [Remainder] winter_solstice_age 天正冬至
114
- #
115
- # @return [SolarTerm] 二十四節気
116
- # SolarTerm.remainder : 入定気(定気の開始点からの日時)
117
- # SolarTerm.index : 定気
118
- #
119
- def self.calc_first_solar_term(winter_solstice_age:)
120
- # 入定気の起算方法
121
- # 概要:
122
- # * 太陽の運行による補正値は、二十四節気の気ごとに定められる
123
- # * 11月経朔の前にある気を求め、それから11月経朔との間隔を求める
124
- # * 気ごとの補正値と、気から11月経朔までにかかる補正値を求める
125
- # 前提:
126
- # * 11月経朔に関わる二十四節気は、時系列から順に、小雪・大雪・冬至である
127
- # * 小雪〜大雪の間隔は小雪定数で、大雪〜冬至の間隔は大雪定数で決められている(24気損益眺朒(ちょうじく)数のこと)
128
- # * 11月経朔は、この小雪〜冬至の間のいずれかにある
129
- # 計算:
130
- # 2パターンある
131
- # (a) 大雪〜冬至にある場合
132
- # *「大雪定数 >= 天正閏余」の場合を指す
133
- # * * NOTE 資料では「より大きい(>)」とされるが、大雪そのものの場合は大雪から起算すべき
134
- # * この場合は、大雪〜経朔の間隔を求める
135
- # (b) 小雪〜大雪にある場合
136
- # *「大雪定数 < 天正閏余」の場合を指す
137
- # * この場合は、小雪〜経朔の間隔を求める
138
-
139
- # NOTE: 上記パターンとは別に、稀だが立冬のパターンも存在する
140
- # この場合は比較方法はそのままに立冬〜経朔の間隔を求める
141
-
142
- rest = winter_solstice_age.clone
143
- # 大雪(23)/小雪(22)/立冬(21)
144
- [23, 22, 21].each do |index|
145
- solar_term = prev_solar_term(winter_solstice_age: rest, index: index)
146
-
147
- if solar_term.invalid?
148
- rest = solar_term.remainder
149
- next
150
- end
151
-
152
- return solar_term
153
- end
154
-
155
- # 立冬(21)を超える天正閏余は成立し得ない(1朔望月をはるかに超えることになる)
156
- raise ArgumentError.new, 'invalid winster solstice age'
157
- end
158
- private_class_method :calc_first_solar_term
159
-
160
- #
161
- # 入気定日加減数で入定気を遡る
162
- #
163
- # @param [Remainder] winter_solstice_age 天正冬至
164
- # @param [Integer] index 二十四節気の連番
165
- #
166
- # @return [SolarTerm] 二十四節気
167
- # SolarTerm.remainder : 入定気(定気の開始点からの日時)
168
- # SolarTerm.index : 定気(範囲外であれば-1とする)
169
- #
170
- def self.prev_solar_term(winter_solstice_age:, index:)
171
- interval = Interval::INDEXES[index]
172
- if winter_solstice_age > interval
173
- # 入定気が確定しない(さらに前の定気まで遡れる)
174
- return Cycle::SolarTerm.new(
175
- remainder: winter_solstice_age.sub(interval),
176
- index: -1
177
- )
178
- end
179
-
180
- # 入定気が確定する
181
- Cycle::SolarTerm.new(
182
- remainder: interval.sub(winter_solstice_age),
183
- index: index
184
- )
185
- end
186
- private_class_method :prev_solar_term
187
-
188
- # :reek:TooManyStatements { max_statements: 8 }
189
-
190
- #
191
- # 次の二十四節気を計算する
192
- #
193
- # @param [SolarTerm] solar_term 今回の二十四節気
194
- #
195
- # @return [SolarTerm] 次回の二十四節気
196
- #
197
- def self.calc_next_solar_term_recursively(solar_term:)
198
- remainder = solar_term.remainder
199
- index = solar_term.index
200
- interval = Interval::INDEXES[index]
201
- return solar_term if remainder < interval
202
-
203
- remainder.sub!(interval)
204
- index += 1
205
- index = 0 if index >= Interval::INDEXES.size
206
- calc_next_solar_term_recursively(
207
- solar_term: Cycle::SolarTerm.new(remainder: remainder, index: index)
208
- )
209
- end
210
- private_class_method :calc_next_solar_term_recursively
211
- end
212
- end
213
- end
@@ -1,213 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../cycle/solar_term'
4
-
5
- # :nodoc:
6
- module Zakuro
7
- # :nodoc:
8
- module Senmyou
9
- #
10
- # SolarOrbit 太陽軌道
11
- #
12
- module SolarOrbit
13
- # @return [Integer] 統法(1日=8400分)
14
- DAY = 8400
15
-
16
- #
17
- # 24気損益眺朒(ちょうじく)数
18
- #
19
- module Adjustment
20
- #
21
- # Item 24気損益眺朒(ちょうじく)数
22
- #
23
- class Item
24
- # @return [Integer] 眺朒(ちょうじく)積
25
- attr_reader :stack
26
- # @return [Integer] 眺朒(ちょうじく)数
27
- attr_reader :per_term
28
- # @return [Integer] 毎日差
29
- attr_reader :per_day
30
-
31
- #
32
- # 初期化
33
- #
34
- # @param [Integer] stack 眺朒(ちょうじく)積
35
- # @param [Integer] per_term 眺朒(ちょうじく)数
36
- # @param [Integer] per_day 毎日差
37
- #
38
- def initialize(stack:, per_term:, per_day:)
39
- @stack = stack
40
- @per_term = per_term
41
- @per_day = per_day
42
- end
43
-
44
- #
45
- # 文字化
46
- #
47
- # @return [String] 文字
48
- #
49
- def to_s
50
- "stack:#{@stack}, per_term:#{@per_term}, per_day:#{@per_day}"
51
- end
52
- end
53
-
54
- # @return [Array<Item>] 24気損益眺朒(ちょうじく)数
55
- LIST = {
56
- touji: Item.new(stack: 0.0, per_term: +33.4511, per_day: -0.3695), # 冬至(とうじ)
57
- shoukan: Item.new(stack: +449.0, per_term: +28.0389, per_day: -0.3606), # 小寒(しょうかん)
58
- daikan: Item.new(stack: +823.0, per_term: +22.6998, per_day: -0.3519), # 大寒(だいかん)
59
- risshun: Item.new(stack: +1122.0, per_term: +17.8923, per_day: -0.4068), # 立春(りっしゅん)
60
- usui: Item.new(stack: +1346.0, per_term: +11.7966, per_day: -0.3998), # 雨水(うすい)
61
- keichitsu: Item.new(stack: +1481.0, per_term: +5.7986, per_day: -0.3998), # 啓蟄(けいちつ)
62
- shunbun: Item.new(stack: +1526.0, per_term: -0.2433, per_day: -0.3779), # 春分(しゅんぶん)
63
- seimei: Item.new(stack: +1481.0, per_term: -6.1254, per_day: -0.3634), # 清明(せいめい)
64
- kokuu: Item.new(stack: +1346.0, per_term: -12.2048, per_day: -0.2987), # 穀雨(こくう)
65
- rikka: Item.new(stack: +1122.0, per_term: -16.9060, per_day: -0.2919), # 立夏(りっか)
66
- shouman: Item.new(stack: +823.0, per_term: -21.5362, per_day: -0.2854), # 小満(しょうまん)
67
- boushu: Item.new(stack: +449.0, per_term: -26.0498, per_day: -0.2854), # 芒種(ぼうしゅ)
68
- geshi: Item.new(stack: 0.0, per_term: -30.3119, per_day: +0.2854), # 夏至(げし)
69
- shousho: Item.new(stack: -449.0, per_term: -25.8126, per_day: +0.2919), # 小暑(しょうしょ)
70
- taisho: Item.new(stack: -823.0, per_term: -21.2454, per_day: +0.2987), # 大暑(たいしょ)
71
- risshuu: Item.new(stack: -1122.0, per_term: -17.0296, per_day: +0.3634), # 立秋(りっしゅう)
72
- shosho: Item.new(stack: -1346.0, per_term: -11.4744, per_day: +0.3779), # 処暑(しょしょ)
73
- hakuro: Item.new(stack: -1481.0, per_term: -5.6429, per_day: +0.3779), # 白露(はくろ)
74
- shuubun: Item.new(stack: -1526.0, per_term: +0.1432, per_day: +0.3998), # 秋分(しゅうぶん)
75
- kanro: Item.new(stack: -1481.0, per_term: +6.1488, per_day: +0.4068), # 寒露(かんろ)
76
- soukou: Item.new(stack: -1346.0, per_term: +12.6336, per_day: +0.3519), # 霜降(そうこう)
77
- rittou: Item.new(stack: -1122.0, per_term: +17.8043, per_day: +0.3606), # 立冬(りっとう)
78
- shousetsu: Item.new(stack: -823.0, per_term: +23.0590, per_day: +0.3695), # 小雪(しょうせつ)
79
- taisetsu: Item.new(stack: -449.0, per_term: +28.4618, per_day: +0.3695) # 大雪(たいせつ)
80
- }.freeze
81
- end
82
-
83
- #
84
- # 太陽の運行による補正値を算出する
85
- #
86
- # @param [SolarTerm] solar_term 入定気
87
- #
88
- # @return [Integer] 補正値
89
- #
90
- def self.calc_sun_orbit_value(solar_term:)
91
- remainder = solar_term.remainder
92
-
93
- adjustment = specify_solar_term_adjustment(index: solar_term.index)
94
- # 損益率/眺朒(ちょうじく)数
95
- # パラメータ:
96
- # a: 眺朒(ちょうじく)数の初日の値
97
- # b: 損益率初日の値
98
- # c: 損益率の毎日の差
99
- # n: 定気の日から数えた日数
100
-
101
- day_stack = calc_day_stack(remainder: remainder, adjustment: adjustment)
102
-
103
- month_stack = calc_month_stack(stack: adjustment.stack, day: remainder.day,
104
- per_term: adjustment.per_term, per_day:
105
- adjustment.per_day)
106
-
107
- # 冬至であれば眺朒数がプラスになり続けて損益率が「益」で、小雪であればマイナスの眺朒数がプラスされ続けて「損」
108
- month_stack + day_stack
109
- end
110
-
111
- #
112
- # 損益率を求める
113
- #
114
- # @param [Remainder] remainder 入定気
115
- # @param [Adjustment::Item] adjustment 24気損益眺朒(ちょうじく)数
116
- #
117
- # @return [Integer] 損益率
118
- #
119
- def self.calc_day_stack(remainder:, adjustment:)
120
- per_term = adjustment.per_term
121
- per_day = adjustment.per_day
122
- sign, ratio = calc_ratio(day: remainder.day, per_term: per_term, per_day: per_day)
123
-
124
- calc_day_stack_from_ratio(sign: sign, ratio: ratio,
125
- minute: remainder.minute)
126
- end
127
- private_class_method :calc_day_stack
128
-
129
- #
130
- # 24気損益眺朒(ちょうじく)数を特定する
131
- #
132
- # @param [Integer] index 連番(二十四節気)
133
- #
134
- # @return [Adjustment::Item] 24気損益眺朒(ちょうじく)数
135
- #
136
- def self.specify_solar_term_adjustment(index:)
137
- key = Cycle::SolarTerm::ORDER[index]
138
- Adjustment::LIST[key].clone
139
- end
140
- private_class_method :specify_solar_term_adjustment
141
-
142
- # :reek:TooManyStatements { max_statements: 6 }
143
-
144
- #
145
- # 大余に対応する損益率を求める
146
- # 損益率 = b + n * c
147
- #
148
- # @param [Integer] day 大余
149
- # @param [Integer] per_term 眺朒(ちょうじく)数
150
- # @param [Integer] per_day 毎日差
151
- #
152
- # @return [Integer] 正負
153
- # @return [Integer] 大余に対応する損益率
154
- #
155
- def self.calc_ratio(day:, per_term:, per_day:)
156
- ratio = per_term + day * per_day
157
- sign = 1
158
- if ratio.negative?
159
- sign = -1
160
- ratio *= sign
161
- end
162
- # 小数点以下は無視する
163
- ratio = ratio.floor
164
-
165
- [sign, ratio]
166
- end
167
- private_class_method :calc_ratio
168
-
169
- #
170
- # 小余を含めた損益率を求める
171
- #
172
- # @param [Integer] sign 正負(大余に対応する損益率)
173
- # @param [Integer] ratio 大余に対応する損益率
174
- # @param [Integer] minute 小余
175
- #
176
- # @return [Integer] 小余を含めた損益率
177
- #
178
- def self.calc_day_stack_from_ratio(sign:, ratio:, minute:)
179
- minute_stack = ratio * minute
180
- day_stack = (minute_stack / DAY).floor
181
- # 四捨五入
182
- # NOTE 資料では「この余りが4200をこえていれば切り上げる」とあり「>=」とした
183
- # 1612年の7月(慶長17年7月)が境界値4200だが、繰り上げを行なっていたため
184
- day_stack += 1 if minute_stack % DAY >= (DAY / 2)
185
- day_stack *= sign
186
-
187
- day_stack
188
- end
189
- private_class_method :calc_day_stack_from_ratio
190
-
191
- # :reek:LongParameterList { max_params: 4 }
192
-
193
- #
194
- # 眺朒(ちょうじく)数を求める
195
- # 眺朒(ちょうじく)数 = a + (n * b) + (1/2)n(n-1)c
196
- #
197
- # @param [Integer] stack 眺朒(ちょうじく)積
198
- # @param [Integer] day 大余
199
- # @param [Integer] per_term 眺朒(ちょうじく)数
200
- # @param [Integer] per_day 毎日差f
201
- #
202
- # @return [Integer] 眺朒(ちょうじく)数
203
- #
204
- def self.calc_month_stack(stack:, day:, per_term:, per_day:)
205
- month_stack = stack + day * per_term + \
206
- (1 / 2.0) * (day * (day - 1) * per_day)
207
- # 切り捨て(プラスマイナスに関わらず小数点以下切り捨て)
208
- month_stack.negative? ? month_stack.ceil : month_stack.floor
209
- end
210
- private_class_method :calc_month_stack
211
- end
212
- end
213
- end