zakuro 0.1.4 → 0.1.5

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