zakuro 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/zakuro/calculation/monthly/abstract_lunar_phase.rb +169 -0
  3. data/lib/zakuro/calculation/range/medieval_annual_range.rb +105 -0
  4. data/lib/zakuro/calculation/stella/lunar/abstract_location.rb +76 -0
  5. data/lib/zakuro/calculation/stella/lunar/choukei_value.rb +52 -0
  6. data/lib/zakuro/calculation/stella/solar/abstract_average.rb +117 -0
  7. data/lib/zakuro/calculation/stella/solar/abstract_location.rb +187 -0
  8. data/lib/zakuro/calculation/stella/solar/choukei_value.rb +136 -0
  9. data/lib/zakuro/calculation/type/old_float.rb +69 -0
  10. data/lib/zakuro/version.rb +1 -1
  11. data/lib/zakuro/version/gihou/const/number.rb +55 -0
  12. data/lib/zakuro/version/gihou/const/remainder.rb +56 -0
  13. data/lib/zakuro/version/gihou/cycle/remainder.rb +61 -0
  14. data/lib/zakuro/version/gihou/cycle/solar_term.rb +34 -0
  15. data/lib/zakuro/version/gihou/gihou.rb +23 -2
  16. data/lib/zakuro/version/gihou/monthly/lunar_phase.rb +106 -0
  17. data/lib/zakuro/version/gihou/range/annual_range.rb +39 -0
  18. data/lib/zakuro/version/gihou/stella/lunar/adjustment.rb +250 -0
  19. data/lib/zakuro/version/gihou/stella/lunar/localization.rb +44 -0
  20. data/lib/zakuro/version/gihou/stella/lunar/location.rb +86 -0
  21. data/lib/zakuro/version/gihou/stella/lunar/value.rb +74 -0
  22. data/lib/zakuro/version/gihou/stella/origin/average_november.rb +34 -0
  23. data/lib/zakuro/version/gihou/stella/origin/lunar_age.rb +62 -0
  24. data/lib/zakuro/version/gihou/stella/origin/winter_solstice.rb +55 -0
  25. data/lib/zakuro/version/gihou/stella/solar/adjustment.rb +93 -0
  26. data/lib/zakuro/version/gihou/stella/solar/average.rb +97 -0
  27. data/lib/zakuro/version/gihou/stella/solar/interval.rb +108 -0
  28. data/lib/zakuro/version/gihou/stella/solar/location.rb +61 -0
  29. data/lib/zakuro/version/gihou/stella/solar/value.rb +36 -0
  30. data/lib/zakuro/version/senmyou/const/number.rb +1 -1
  31. data/lib/zakuro/version/senmyou/const/remainder.rb +7 -1
  32. data/lib/zakuro/version/senmyou/cycle/solar_term.rb +4 -1
  33. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +11 -111
  34. data/lib/zakuro/version/senmyou/range/annual_range.rb +5 -77
  35. data/lib/zakuro/version/senmyou/stella/lunar/localization.rb +2 -3
  36. data/lib/zakuro/version/senmyou/stella/lunar/location.rb +13 -28
  37. data/lib/zakuro/version/senmyou/stella/lunar/value.rb +5 -28
  38. data/lib/zakuro/version/senmyou/stella/solar/adjustment.rb +29 -29
  39. data/lib/zakuro/version/senmyou/stella/solar/average.rb +11 -89
  40. data/lib/zakuro/version/senmyou/stella/solar/location.rb +18 -121
  41. data/lib/zakuro/version/senmyou/stella/solar/value.rb +4 -103
  42. data/lib/zakuro/version/version_class_resolver.rb +4 -0
  43. metadata +28 -2
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../cycle/remainder'
4
+
5
+ # :nodoc:
6
+ module Zakuro
7
+ # :nodoc:
8
+ module Gihou
9
+ #
10
+ # Const 定数
11
+ #
12
+ module Const
13
+ #
14
+ # Remainder 大余小余
15
+ #
16
+ module Remainder
17
+ #
18
+ # Solar 太陽
19
+ #
20
+ module Solar
21
+ # @return [Remainder] 気策(24分の1年)
22
+ SOLAR_TERM_AVERAGE = Cycle::Remainder.new(day: 15, minute: 292, second: 5)
23
+ #
24
+ # @note 常朔実 39571 = 29-711
25
+ # * 39571 / 4 = 9892.75 / 1340 = 7 余り 512.75
26
+ # * 0.75 * 6(1分=6秒) = 4.5
27
+ #
28
+ # @return [Cycle::Remainder] 弦(1分=6秒)
29
+ QUARTER = Cycle::Remainder.new(day: 7, minute: 512, second: 4.5)
30
+ end
31
+
32
+ #
33
+ # Lunar 月
34
+ #
35
+ module Lunar
36
+ # @return [Cycle::LunarRemainder] 変日(1近点月)
37
+ ANOMALISTIC_MONTH = \
38
+ Cycle::LunarRemainder.new(day: 27, minute: 743, second: 1)
39
+ # @return [Cycle::LunarRemainder] 入暦上限
40
+ LIMIT = Cycle::LunarRemainder.new(day: 28, minute: 743, second: 0)
41
+ #
42
+ # @note 常朔実 39571 = 29-711
43
+ # * 39571 / 4 = 9892.75 / 1340 = 7 余り 512.75
44
+ # * 0.75 * 12(1分=12秒) = 9
45
+ #
46
+ # @return [Cycle::LunarRemainder] 弦(1分=12秒)
47
+ # TODO: 9秒だと通らない。 0.00378 〜 0.0208 の範囲内で通る
48
+ # QUARTER = Cycle::LunarRemainder.new(day: 7, minute: 512, second: 9)
49
+ # QUARTER = Cycle::LunarRemainder.new(day: 7, minute: 512, second: 9.00378)
50
+ # QUARTER = Cycle::LunarRemainder.new(day: 7, minute: 512, second: 9.0208)
51
+ QUARTER = Cycle::LunarRemainder.new(day: 7, minute: 512, second: 9.00378)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../calculation/cycle/abstract_remainder'
4
+
5
+ require_relative '../const/number'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ # :nodoc:
10
+ module Gihou
11
+ # :nodoc:
12
+ module Cycle
13
+ #
14
+ # Remainder 宣明暦の時刻情報(大余小余)
15
+ #
16
+ # * 「15日1012分5秒」のような形式で表される
17
+ # * 分は1340で一日に繰り上げる
18
+ # * 秒は基本的に1/6分で、6秒で1分に繰り上げる。ただし、月補正値は1分に100秒とするなど基数の変更がありえる
19
+ # * 十干十二支(60日)を上限とした「日時分秒」の情報で、日付(date)/時刻(time)と部分的に重なる概念
20
+ #
21
+ class Remainder < Calculation::Cycle::AbstractRemainder
22
+ # @return [Integer] 分(1分=6秒)
23
+ MINUTE = 6
24
+
25
+ #
26
+ # 初期化
27
+ #
28
+ # @param [Integer] day 大余("日"に相当)
29
+ # @param [Integer] minute 小余("分"に相当)
30
+ # @param [Integer] second 秒
31
+ # @param [Integer] total 繰り上げなしの小余
32
+ #
33
+ def initialize(day: -1, minute: -1, second: -1, total: -1)
34
+ super(base_day: Const::Number::Cycle::DAY, base_mitune: MINUTE,
35
+ day: day, minute: minute, second: second, total: total)
36
+ end
37
+ end
38
+
39
+ #
40
+ # LunarRemainder 月の位相計算向け時刻情報(大余小余)
41
+ #
42
+ class LunarRemainder < Calculation::Cycle::AbstractRemainder
43
+ # @return [Integer] 分(1分=12秒)
44
+ MINUTE = 12
45
+
46
+ #
47
+ # 初期化
48
+ #
49
+ # @param [Integer] day 大余("日"に相当)
50
+ # @param [Integer] minute 小余("分"に相当)
51
+ # @param [Integer] second 秒
52
+ # @param [Integer] total 繰り上げなしの小余
53
+ #
54
+ def initialize(day: -1, minute: -1, second: -1, total: -1)
55
+ super(base_day: Const::Number::Cycle::DAY, base_mitune: MINUTE,
56
+ day: day, minute: minute, second: second, total: total)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../calculation/cycle/abstract_solar_term'
4
+
5
+ require_relative '../const/remainder'
6
+
7
+ require_relative './remainder'
8
+
9
+ # :nodoc:
10
+ module Zakuro
11
+ # :nodoc:
12
+ module Gihou
13
+ # :nodoc:
14
+ module Cycle
15
+ #
16
+ # SolarTerm 二十四節気
17
+ #
18
+ class SolarTerm < Calculation::Cycle::AbstractSolarTerm
19
+ # @return [Remainder] 気策(24分の1年)
20
+ SOLAR_TERM_AVERAGE = Const::Remainder::Solar::SOLAR_TERM_AVERAGE
21
+
22
+ #
23
+ # 初期化
24
+ #
25
+ # @param [Integer] index 連番
26
+ # @param [Remainder] remainder 時刻情報(大余小余)
27
+ #
28
+ def initialize(index: -1, remainder: Remainder.new)
29
+ super(index: index, remainder: remainder, average: SOLAR_TERM_AVERAGE)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'date'
4
+ require_relative '../../era/western'
3
5
  require_relative '../abstract_version'
6
+ require_relative '../context'
7
+ require_relative '../../calculation/summary/single'
4
8
 
5
9
  # :nodoc:
6
10
  module Zakuro
@@ -12,8 +16,25 @@ module Zakuro
12
16
  # Gateway アクセサメソッド群
13
17
  #
14
18
  class Gateway < AbstractVersion
15
- # @return [False] リリースなし
16
- RELEASE = false
19
+ # @return [True] リリースあり
20
+ RELEASE = true
21
+
22
+ # @return [String] 暦クラス名
23
+ VERSION_NAME = 'Gihou'
24
+
25
+ #
26
+ # 西暦日から和暦日に変換する
27
+ #
28
+ # @param [Date] western_date 西暦日
29
+ #
30
+ # @return [Result::Single] 和暦日
31
+ #
32
+ def self.to_japan_date(western_date:)
33
+ date = Western::Calendar.create(date: western_date)
34
+
35
+ context = Context.new(version_name: VERSION_NAME)
36
+ Calculation::Summary::Single.get(context: context, date: date)
37
+ end
17
38
  end
18
39
  end
19
40
  end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../calculation/monthly/abstract_lunar_phase'
4
+
5
+ require_relative '../const/remainder'
6
+
7
+ require_relative '../stella/solar/location'
8
+ require_relative '../stella/solar/value'
9
+ require_relative '../stella/lunar/location'
10
+ require_relative '../stella/lunar/value'
11
+
12
+ require_relative '../stella/origin/lunar_age'
13
+ require_relative '../stella/origin/average_november'
14
+
15
+ # :nodoc:
16
+ module Zakuro
17
+ # :nodoc:
18
+ module Gihou
19
+ # :nodoc:
20
+ module Monthly
21
+ #
22
+ # LunarPhase 月の位相
23
+ #
24
+ class LunarPhase < Calculation::Monthly::AbstractLunarPhase
25
+ # @return [Cycle::Remainder] 弦
26
+ QUARTER = Const::Remainder::Solar::QUARTER
27
+
28
+ #
29
+ # 初期化
30
+ #
31
+ # @param [Integer] western_year 西暦年
32
+ #
33
+ def initialize(western_year:)
34
+ # 天正閏余
35
+ lunar_age = Origin::LunarAge.get(western_year: western_year)
36
+
37
+ super(
38
+ quater: QUARTER,
39
+ average_remainder: Origin::AverageNovember.get(western_year: western_year),
40
+ solar_location: Solar::Location.new(lunar_age: lunar_age),
41
+ lunar_location: Lunar::Location.new(
42
+ western_year: western_year,
43
+ lunar_age: Cycle::LunarRemainder.new(total: 0).add!(lunar_age)
44
+ )
45
+ )
46
+ end
47
+
48
+ private
49
+
50
+ # :reek:TooManyStatements { max_statements: 6 }
51
+
52
+ #
53
+ # 現在の定朔を取得する
54
+ #
55
+ # @return [Remainder] 定朔
56
+ #
57
+ def current_remainder
58
+ # debug("@average_remainder.format: #{@average_remainder.format(form: '%d-%d-%.5f')}")
59
+
60
+ sum = correction_value
61
+ adjusted = @average_remainder.add(
62
+ Cycle::Remainder.new(day: 0, minute: sum, second: 0)
63
+ )
64
+ # NOTE: 儀鳳暦では進朔しない
65
+ # adjusted.up_on_new_moon!
66
+
67
+ debug("result: #{adjusted.format}")
68
+
69
+ adjusted
70
+ end
71
+
72
+ #
73
+ # 太陽運動の補正値を得る
74
+ #
75
+ # @return [Integer] 太陽運動の補正値
76
+ #
77
+ def correction_solar_value
78
+ @solar_location.run
79
+ # debug("@solar_term.remainder: #{@solar_location.remainder.format(form: '%d-%d-%.5f')}")
80
+ # debug("@solar_term.index: #{@solar_location.index}")
81
+
82
+ Solar::Value.get(solar_location: @solar_location)
83
+ end
84
+
85
+ # :reek:TooManyStatements { max_statements: 6 }
86
+
87
+ #
88
+ # 月運動の補正値を得る
89
+ #
90
+ # @return [Integer] 月運動の補正値
91
+ #
92
+ def correction_moon_value
93
+ @lunar_location.run
94
+
95
+ remainder = @lunar_location.remainder
96
+
97
+ # debug("[lunar]remainder.format: #{remainder.format(form: '%d-%d-%.5f')}")
98
+ # debug("[lunar]remainder.day: #{remainder.day}")
99
+ # debug("[lunar]remainder.minute: #{remainder.minute}")
100
+
101
+ Lunar::Value.get(remainder: remainder)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../calculation/range/medieval_annual_range'
4
+ require_relative '../monthly/lunar_phase'
5
+ require_relative '../stella/solar/average'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ # :nodoc:
10
+ module Gihou
11
+ # :nodoc:
12
+ module Range
13
+ #
14
+ # AnnualRange 年間範囲
15
+ #
16
+ module AnnualRange
17
+ #
18
+ # 一覧取得する
19
+ #
20
+ # * 対象年に対して、前年11月-当年11月までを出力する
21
+ # * 対象年(西暦)と計算年(元号x年)の紐付けは行わない
22
+ #
23
+ # @param [Context] context 暦コンテキスト
24
+ # @param [Integer] western_year 西暦年
25
+ #
26
+ # @return [Array<Month>] 1年データ
27
+ #
28
+ def self.get(context:, western_year:)
29
+ lunar_phase = Monthly::LunarPhase.new(western_year: western_year)
30
+ solar_average = Solar::Average.new(western_year: western_year)
31
+
32
+ Calculation::Range::MedievalAnnualRange.get(
33
+ context: context, lunar_phase: lunar_phase, solar_average: solar_average
34
+ )
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,250 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../const/number'
4
+
5
+ # :nodoc:
6
+ module Zakuro
7
+ # :nodoc:
8
+ module Gihou
9
+ # :nodoc:
10
+ module Lunar
11
+ #
12
+ # Adjustment 補正値情報
13
+ #
14
+ module Adjustment
15
+ #
16
+ # 遠/近の地点での中間
17
+ #
18
+ # 7、14、21日の小余の境界は下記のようにして求めた
19
+ # * 宣明暦の7日の小余は7465である。入暦は1始まりなので、0始まりで表現すると 6-7465 となる
20
+ # * 6 * 8400(統法) + 7465(初益) = 57865
21
+ # * これを儀鳳暦に変えると、 57865 / 1340(総法) = 6 余り 1190.845238..
22
+ # * これを入暦の1始まりに置き換え、少数部を消すと 7-1190、これが7日目となる
23
+ # * 同様の方法で14日と21日も求める
24
+ # * 57865 * 2 = 115730 / 1340(総法) = 13 余り 1041.690476 = 14-1041
25
+ # * 57865 * 3 = 173595 / 1340(総法) = 20 余り 892.5357143 = 21-892
26
+ #
27
+ # 28日は変日の範囲内743とした。
28
+ # * 宣明暦では 進退 14-6529(1始まりなので実質13) * 2 = 27-4658
29
+ # * 暦周 27-4658.19 に一致する。これを変日27-743.1と同等とみなした
30
+ #
31
+ # @return [Hash<Integer>] 遠/近の地点での中間
32
+ DAY_LIMIT = {
33
+ 7 => 1191, # 天平勝宝2年(750年)5月 により 1190 ではないことを確認した
34
+ 14 => 1042, # 養老6年(722年) 6月 により 1041 ではないことを確認した
35
+ 21 => 892,
36
+ 28 => 743.06 # 天平13年(741年) 2月 により 743 ではないことを確認した
37
+ }.freeze
38
+
39
+ #
40
+ # Row 行情報
41
+ #
42
+ class Row
43
+ # @return [Integer] 入暦(1-14)
44
+ attr_reader :day
45
+ # @return [Range] 小余範囲
46
+ attr_reader :range
47
+ # @return [Value] 補正値
48
+ attr_reader :value
49
+
50
+ #
51
+ # 初期化
52
+ #
53
+ # @param [Integer] day 入暦(1-14)
54
+ # @param [Range] range 小余範囲
55
+ # @param [Value] value 補正値
56
+ #
57
+ def initialize(day:, range:, value:)
58
+ @day = day
59
+ @range = range
60
+ @value = value
61
+ end
62
+
63
+ # :reek:ControlParameter
64
+
65
+ #
66
+ # 一致するか
67
+ #
68
+ # @param [Integer] day 入暦(1-14)
69
+ # @param [Integer] minute 小余
70
+ #
71
+ # @return [True] 一致
72
+ # @return [False] 不一致
73
+ #
74
+ def match?(day:, minute:)
75
+ return false unless @day == day
76
+
77
+ return false unless @range.include?(minute: minute)
78
+
79
+ true
80
+ end
81
+
82
+ #
83
+ # 分母を返す
84
+ #
85
+ # @return [Integer] 分母
86
+ #
87
+ def denominator
88
+ @range.denominator
89
+ end
90
+ end
91
+
92
+ #
93
+ # Range 小余範囲
94
+ #
95
+ class Range
96
+ # @return [Integer] 下限
97
+ MIN = 0
98
+ # @return [Integer] 上限
99
+ MAX = Const::Number::Cycle::DAY
100
+
101
+ # @return [Integer] 下限
102
+ attr_reader :min
103
+ # @return [Integer] 上限
104
+ attr_reader :max
105
+
106
+ #
107
+ # 初期化
108
+ #
109
+ # @param [Integer] min 下限
110
+ # @param [Integer] max 上限
111
+ #
112
+ def initialize(min: MIN, max: MAX)
113
+ @min = min
114
+ @max = max
115
+ end
116
+
117
+ #
118
+ # 含まれるか
119
+ #
120
+ # @param [Integer] minute 小余
121
+ #
122
+ # @return [True] 含まれる
123
+ # @return [False] 含まれない
124
+ #
125
+ def include?(minute:)
126
+ minute >= @min && minute <= @max
127
+ end
128
+
129
+ #
130
+ # 分母を返す
131
+ #
132
+ # @return [Integer] 分母
133
+ #
134
+ def denominator
135
+ @max - @min
136
+ end
137
+ end
138
+
139
+ #
140
+ # Value 補正値
141
+ #
142
+ class Value
143
+ # @return [Integer] 増減率
144
+ attr_reader :per
145
+ # @return [Integer] 遅速積
146
+ attr_reader :stack
147
+
148
+ #
149
+ # 初期化
150
+ #
151
+ # @param [Integer] per 増減率
152
+ # @param [Integer] stack 遅速積
153
+ #
154
+ def initialize(per:, stack:)
155
+ @per = per
156
+ @stack = stack
157
+ end
158
+
159
+ #
160
+ # 文字化
161
+ #
162
+ # @return [String] 文字
163
+ #
164
+ def to_s
165
+ "per:#{@per}, stack:#{@stack}"
166
+ end
167
+ end
168
+
169
+ # rubocop:disable Layout/LineLength
170
+
171
+ # @note 7日、14日、21日、28日の小余は DAY_LIMIT を参照のこと
172
+ #
173
+ # @return [Array<Row>] 月の補正値情報
174
+ #
175
+ LIST = [
176
+ Row.new(day: 1, range: Range.new, value: Value.new(per: -134, stack: 0)),
177
+ Row.new(day: 2, range: Range.new, value: Value.new(per: -117, stack: -134)),
178
+ Row.new(day: 3, range: Range.new, value: Value.new(per: -99, stack: -251)),
179
+ Row.new(day: 4, range: Range.new, value: Value.new(per: -78, stack: -350)),
180
+ Row.new(day: 5, range: Range.new, value: Value.new(per: -56, stack: -428)),
181
+ Row.new(day: 6, range: Range.new, value: Value.new(per: -33, stack: -484)),
182
+ Row.new(day: 7, range: Range.new(max: DAY_LIMIT[7]), value: Value.new(per: -9, stack: -517)),
183
+ Row.new(day: 7, range: Range.new(min: DAY_LIMIT[7]), value: Value.new(per: 0, stack: -526)),
184
+ Row.new(day: 8, range: Range.new, value: Value.new(per: +14, stack: -526)),
185
+ Row.new(day: 9, range: Range.new, value: Value.new(per: +38, stack: -512)),
186
+ Row.new(day: 10, range: Range.new, value: Value.new(per: +62, stack: -474)),
187
+ Row.new(day: 11, range: Range.new, value: Value.new(per: +85, stack: -412)),
188
+ Row.new(day: 12, range: Range.new, value: Value.new(per: +104, stack: -327)),
189
+ Row.new(day: 13, range: Range.new, value: Value.new(per: +121, stack: -223)),
190
+ Row.new(day: 14, range: Range.new(max: DAY_LIMIT[14]), value: Value.new(per: +102, stack: -102)),
191
+ Row.new(day: 14, range: Range.new(min: DAY_LIMIT[14]), value: Value.new(per: +29, stack: 0)),
192
+ Row.new(day: 15, range: Range.new, value: Value.new(per: +128, stack: +29)),
193
+ Row.new(day: 16, range: Range.new, value: Value.new(per: +115, stack: +157)),
194
+ Row.new(day: 17, range: Range.new, value: Value.new(per: +95, stack: +272)),
195
+ Row.new(day: 18, range: Range.new, value: Value.new(per: +74, stack: +367)),
196
+ Row.new(day: 19, range: Range.new, value: Value.new(per: +52, stack: +441)),
197
+ Row.new(day: 20, range: Range.new, value: Value.new(per: +28, stack: +493)),
198
+ Row.new(day: 21, range: Range.new(max: DAY_LIMIT[21]), value: Value.new(per: +4, stack: +521)),
199
+ Row.new(day: 21, range: Range.new(min: DAY_LIMIT[21]), value: Value.new(per: 0, stack: +525)),
200
+ Row.new(day: 22, range: Range.new, value: Value.new(per: -20, stack: +525)),
201
+ Row.new(day: 23, range: Range.new, value: Value.new(per: -44, stack: +505)),
202
+ Row.new(day: 24, range: Range.new, value: Value.new(per: -68, stack: +461)),
203
+ Row.new(day: 25, range: Range.new, value: Value.new(per: -89, stack: +393)),
204
+ Row.new(day: 26, range: Range.new, value: Value.new(per: -108, stack: +304)),
205
+ Row.new(day: 27, range: Range.new, value: Value.new(per: -125, stack: +196)),
206
+ Row.new(day: 28, range: Range.new(max: DAY_LIMIT[28]), value: Value.new(per: -71, stack: +71))
207
+ ].freeze
208
+ # rubocop:enable Layout/LineLength
209
+
210
+ #
211
+ # 月軌道の補正に必要な基本値を引き当てる
212
+ #
213
+ # @param [True, False] forward 進(遠地点より数える)/退(近地点より数える)
214
+ # @param [Integer] day 大余
215
+ # @param [Integer] minute 小余
216
+ #
217
+ # @return [Row] 補正値
218
+ #
219
+ def self.specify(day:, minute:)
220
+ LIST.each do |row|
221
+ # NOTE: 範囲が重複している場合、最初に引き当てたほうを優先する
222
+ return row if row.match?(day: day, minute: minute)
223
+ end
224
+
225
+ raise ArgumentError.new, "invalid parameter: #{day}/#{minute}"
226
+ end
227
+
228
+ # :reek:ControlParameter
229
+
230
+ #
231
+ # 小余の下げ幅を求める
232
+ #
233
+ # @param [Integer] day 大余
234
+ # @param [Integer] minute 小余
235
+ #
236
+ # @return [Integer] 小余の下げ幅
237
+ #
238
+ def self.minus_minute(day:, minute:)
239
+ limit = DAY_LIMIT.fetch(day, -1)
240
+ # 該当なし
241
+ return minute if limit == -1
242
+
243
+ return minute unless minute > limit
244
+
245
+ minute - limit
246
+ end
247
+ end
248
+ end
249
+ end
250
+ end