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
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../const/remainder'
4
+
5
+ require_relative './interval'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ # :nodoc:
10
+ module Senmyou
11
+ # :nodoc:
12
+ module Solar
13
+ #
14
+ # Location 入定気
15
+ #
16
+ class Location
17
+ # @return [Cycle::Remainder] 弦
18
+ QUARTER = Const::Remainder::Solar::QUARTER
19
+
20
+ # @return [True] 計算済み(前回計算あり)
21
+ # @return [False] 未計算(初回計算)
22
+ attr_reader :calculated
23
+ # @return [Integer] 連番
24
+ attr_reader :index
25
+ # @return [Cycle::Remainder] 大余小余
26
+ attr_reader :remainder
27
+
28
+ #
29
+ # 初期化
30
+ #
31
+ # @param [Cycle::Remainder] lunar_age 天正閏余(大余小余)
32
+ #
33
+ def initialize(lunar_age: Cycle::Remainder.new)
34
+ @calculated = false
35
+ @index = -1
36
+ @remainder = lunar_age.clone
37
+ end
38
+
39
+ #
40
+ # 入定気を計算する
41
+ #
42
+ def run
43
+ return current if calculated
44
+
45
+ first
46
+ end
47
+
48
+ #
49
+ # 無効かどうか
50
+ #
51
+ # @return [True] 無効
52
+ # @return [False] 有効
53
+ #
54
+ def invalid?
55
+ @index == -1
56
+ end
57
+
58
+ #
59
+ # 弦の分だけ太陽地点を進める
60
+ #
61
+ def add_quarter
62
+ @remainder.add!(QUARTER)
63
+ end
64
+
65
+ private
66
+
67
+ #
68
+ # 2回目以降の計算をする
69
+ #
70
+ def current
71
+ decrease_recursively
72
+ end
73
+
74
+ #
75
+ # 初回計算する
76
+ #
77
+ def first
78
+ define_first
79
+ @calculated = true
80
+ end
81
+
82
+ #
83
+ # 初回の入定気を定める
84
+ #
85
+ def define_first
86
+ # 入定気の起算方法
87
+ # 概要:
88
+ # * 太陽の運行による補正値は、二十四節気の気ごとに定められる
89
+ # * 11月経朔の前にある気を求め、それから11月経朔との間隔を求める
90
+ # * 気ごとの補正値と、気から11月経朔までにかかる補正値を求める
91
+ # 前提:
92
+ # * 11月経朔に関わる二十四節気は、時系列から順に、小雪・大雪・冬至である
93
+ # * 小雪〜大雪の間隔は小雪定数で、大雪〜冬至の間隔は大雪定数で決められている(24気損益眺朒(ちょうじく)数のこと)
94
+ # * 11月経朔は、この小雪〜冬至の間のいずれかにある
95
+ # 計算:
96
+ # 2パターンある
97
+ # (a) 大雪〜冬至にある場合
98
+ # *「大雪定数 >= 天正閏余」の場合を指す
99
+ # * * NOTE 資料では「より大きい(>)」とされるが、大雪そのものの場合は大雪から起算すべき
100
+ # * この場合は、大雪〜経朔の間隔を求める
101
+ # (b) 小雪〜大雪にある場合
102
+ # *「大雪定数 < 天正閏余」の場合を指す
103
+ # * この場合は、小雪〜経朔の間隔を求める
104
+
105
+ # NOTE: 上記パターンとは別に、稀だが立冬のパターンも存在する
106
+ # この場合は比較方法はそのままに立冬〜経朔の間隔を求める
107
+
108
+ # 大雪(23)/小雪(22)/立冬(21)
109
+ [23, 22, 21].each do |index|
110
+ prev(index: index)
111
+
112
+ break unless invalid?
113
+ end
114
+
115
+ # 立冬(21)を超える天正閏余は成立し得ない(1朔望月をはるかに超えることになる)
116
+ return unless invalid?
117
+
118
+ raise ArgumentError.new, 'invalid winster solstice age'
119
+ end
120
+
121
+ #
122
+ # 大余小余の分だけ二十四節気を遡る
123
+ #
124
+ # @param [Integer] index 二十四節気番号
125
+ #
126
+ def prev(index:)
127
+ interval = Interval.index_of(index)
128
+ if remainder > interval
129
+ @remainder.sub!(interval)
130
+ return
131
+ end
132
+
133
+ # 入定気が確定する
134
+ @remainder = interval.sub(@remainder)
135
+ @index = index
136
+ end
137
+
138
+ #
139
+ # 二十四節気番号を次に進める
140
+ #
141
+ def next_index
142
+ @index += 1
143
+ @index = 0 if @index >= Interval.size
144
+ end
145
+
146
+ #
147
+ # 二十四節気を減算する
148
+ #
149
+ def decrease_recursively
150
+ interval = Interval.index_of(@index)
151
+ # 現在の二十四節気に留まる
152
+ return if remainder < interval
153
+
154
+ @remainder.sub!(interval)
155
+
156
+ next_index
157
+
158
+ # 再帰
159
+ decrease_recursively
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../const/number'
4
+
5
+ require_relative './adjustment'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ # :nodoc:
10
+ module Senmyou
11
+ # :nodoc:
12
+ module Solar
13
+ #
14
+ # Value 太陽補正値
15
+ #
16
+ module Value
17
+ # @return [Integer] 1日
18
+ DAY = Const::Number::Cycle::DAY
19
+
20
+ #
21
+ # 太陽の運行による補正値を算出する
22
+ #
23
+ # @param [SolarTerm] solar_location 入定気
24
+ #
25
+ # @return [Integer] 補正値
26
+ #
27
+ def self.get(solar_location:)
28
+ remainder = solar_location.remainder
29
+
30
+ adjustment = Adjustment.specify(index: solar_location.index)
31
+ # 損益率/眺朒(ちょうじく)数
32
+ # パラメータ:
33
+ # a: 眺朒(ちょうじく)数の初日の値
34
+ # b: 損益率初日の値
35
+ # c: 損益率の毎日の差
36
+ # n: 定気の日から数えた日数
37
+
38
+ day_stack = calc_day_stack(remainder: remainder, adjustment: adjustment)
39
+
40
+ month_stack = calc_month_stack(stack: adjustment.stack, day: remainder.day,
41
+ per_term: adjustment.per_term, per_day:
42
+ adjustment.per_day)
43
+
44
+ # 冬至であれば眺朒数がプラスになり続けて損益率が「益」で、小雪であればマイナスの眺朒数がプラスされ続けて「損」
45
+ month_stack + day_stack
46
+ end
47
+
48
+ #
49
+ # 損益率を求める
50
+ #
51
+ # @param [Remainder] remainder 入定気
52
+ # @param [Adjustment::Item] adjustment 24気損益眺朒(ちょうじく)数
53
+ #
54
+ # @return [Integer] 損益率
55
+ #
56
+ def self.calc_day_stack(remainder:, adjustment:)
57
+ per_term = adjustment.per_term
58
+ per_day = adjustment.per_day
59
+ sign, ratio = calc_ratio(day: remainder.day, per_term: per_term, per_day: per_day)
60
+
61
+ calc_day_stack_from_ratio(sign: sign, ratio: ratio,
62
+ minute: remainder.minute)
63
+ end
64
+ private_class_method :calc_day_stack
65
+
66
+ # :reek:TooManyStatements { max_statements: 6 }
67
+
68
+ #
69
+ # 大余に対応する損益率を求める
70
+ # 損益率 = b + n * c
71
+ #
72
+ # @param [Integer] day 大余
73
+ # @param [Integer] per_term 眺朒(ちょうじく)数
74
+ # @param [Integer] per_day 毎日差
75
+ #
76
+ # @return [Integer] 正負
77
+ # @return [Integer] 大余に対応する損益率
78
+ #
79
+ def self.calc_ratio(day:, per_term:, per_day:)
80
+ ratio = per_term + day * per_day
81
+ sign = 1
82
+ if ratio.negative?
83
+ sign = -1
84
+ ratio *= sign
85
+ end
86
+ # 小数点以下は無視する
87
+ ratio = ratio.floor
88
+
89
+ [sign, ratio]
90
+ end
91
+ private_class_method :calc_ratio
92
+
93
+ #
94
+ # 小余を含めた損益率を求める
95
+ #
96
+ # @param [Integer] sign 正負(大余に対応する損益率)
97
+ # @param [Integer] ratio 大余に対応する損益率
98
+ # @param [Integer] minute 小余
99
+ #
100
+ # @return [Integer] 小余を含めた損益率
101
+ #
102
+ def self.calc_day_stack_from_ratio(sign:, ratio:, minute:)
103
+ minute_stack = ratio * minute
104
+ day_stack = (minute_stack / DAY).floor
105
+ # 四捨五入
106
+ # NOTE 資料では「この余りが4200をこえていれば切り上げる」とあり「>=」とした
107
+ # 1612年の7月(慶長17年7月)が境界値4200だが、繰り上げを行なっていたため
108
+ day_stack += 1 if minute_stack % DAY >= (DAY / 2)
109
+ day_stack *= sign
110
+
111
+ day_stack
112
+ end
113
+ private_class_method :calc_day_stack_from_ratio
114
+
115
+ # :reek:LongParameterList { max_params: 4 }
116
+
117
+ #
118
+ # 眺朒(ちょうじく)数を求める
119
+ # 眺朒(ちょうじく)数 = a + (n * b) + (1/2)n(n-1)c
120
+ #
121
+ # @param [Integer] stack 眺朒(ちょうじく)積
122
+ # @param [Integer] day 大余
123
+ # @param [Integer] per_term 眺朒(ちょうじく)数
124
+ # @param [Integer] per_day 毎日差f
125
+ #
126
+ # @return [Integer] 眺朒(ちょうじく)数
127
+ #
128
+ def self.calc_month_stack(stack:, day:, per_term:, per_day:)
129
+ month_stack = stack + day * per_term + \
130
+ (1 / 2.0) * (day * (day - 1) * per_day)
131
+ # 切り捨て(プラスマイナスに関わらず小数点以下切り捨て)
132
+ month_stack.negative? ? month_stack.ceil : month_stack.floor
133
+ end
134
+ private_class_method :calc_month_stack
135
+ end
136
+ end
137
+ end
138
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zakuro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - pldb
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-03 00:00:00.000000000 Z
11
+ date: 2021-05-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: mainly lunar solar calendar
14
14
  email:
@@ -93,16 +93,25 @@ files:
93
93
  - lib/zakuro/version/joukyou/joukyou.rb
94
94
  - lib/zakuro/version/kansei/kansei.rb
95
95
  - lib/zakuro/version/senmyou/README.md
96
+ - lib/zakuro/version/senmyou/const/number.rb
97
+ - lib/zakuro/version/senmyou/const/remainder.rb
96
98
  - lib/zakuro/version/senmyou/cycle/remainder.rb
97
99
  - lib/zakuro/version/senmyou/cycle/solar_term.rb
98
100
  - lib/zakuro/version/senmyou/monthly/lunar_phase.rb
99
101
  - lib/zakuro/version/senmyou/range/annual_range.rb
100
102
  - lib/zakuro/version/senmyou/senmyou.rb
101
- - lib/zakuro/version/senmyou/stella/lunar_orbit.rb
102
- - lib/zakuro/version/senmyou/stella/solar_average.rb
103
- - lib/zakuro/version/senmyou/stella/solar_location.rb
104
- - lib/zakuro/version/senmyou/stella/solar_orbit.rb
105
- - lib/zakuro/version/senmyou/stella/winter_solstice.rb
103
+ - lib/zakuro/version/senmyou/stella/lunar/adjustment.rb
104
+ - lib/zakuro/version/senmyou/stella/lunar/localization.rb
105
+ - lib/zakuro/version/senmyou/stella/lunar/location.rb
106
+ - lib/zakuro/version/senmyou/stella/lunar/value.rb
107
+ - lib/zakuro/version/senmyou/stella/origin/average_november.rb
108
+ - lib/zakuro/version/senmyou/stella/origin/lunar_age.rb
109
+ - lib/zakuro/version/senmyou/stella/origin/winter_solstice.rb
110
+ - lib/zakuro/version/senmyou/stella/solar/adjustment.rb
111
+ - lib/zakuro/version/senmyou/stella/solar/average.rb
112
+ - lib/zakuro/version/senmyou/stella/solar/interval.rb
113
+ - lib/zakuro/version/senmyou/stella/solar/location.rb
114
+ - lib/zakuro/version/senmyou/stella/solar/value.rb
106
115
  - lib/zakuro/version/taien/taien.rb
107
116
  - lib/zakuro/version/tenpou/tenpou.rb
108
117
  - lib/zakuro/version/version_class_resolver.rb
@@ -116,7 +125,7 @@ metadata:
116
125
  homepage_uri: https://github.com/pldb/zakuro
117
126
  source_code_uri: https://github.com/pldb/zakuro
118
127
  changelog_uri: https://github.com/pldb/zakuro
119
- post_install_message:
128
+ post_install_message:
120
129
  rdoc_options: []
121
130
  require_paths:
122
131
  - lib
@@ -131,8 +140,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
140
  - !ruby/object:Gem::Version
132
141
  version: '0'
133
142
  requirements: []
134
- rubygems_version: 3.1.2
135
- signing_key:
143
+ rubygems_version: 3.1.4
144
+ signing_key:
136
145
  specification_version: 4
137
146
  summary: japanese calendar library.
138
147
  test_files: []
@@ -1,332 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # :nodoc:
4
- module Zakuro
5
- # :nodoc:
6
- module Senmyou
7
- #
8
- # LunarOrbit 月軌道
9
- #
10
- module LunarOrbit
11
- # @return [Integer] 暦周(1近日点)
12
- ANOMALISTIC_MONTH = 231_458.19
13
- # @return [Integer] 暦中日
14
- # @note ANOMALISTIC_MONTH の半分に相当する
15
- HALF_ANOMALISTIC_MONTH = \
16
- Cycle::LunarRemainder.new(day: 13, minute: 6529, second: 9.5)
17
-
18
- #
19
- # Adjustment 補正値情報
20
- #
21
- module Adjustment
22
- #
23
- # Item 補正値
24
- #
25
- class Item
26
- # @return [Integer] 損益率
27
- attr_reader :per
28
- # @return [Integer] 眺朒(ちょうじく)積
29
- attr_reader :stack
30
-
31
- #
32
- # 初期化
33
- #
34
- # @param [Integer] per 損益率
35
- # @param [Integer] stack 眺朒(ちょうじく)積
36
- #
37
- def initialize(per:, stack:)
38
- @per = per
39
- @stack = stack
40
- end
41
-
42
- #
43
- # 文字化
44
- #
45
- # @return [String] 文字
46
- #
47
- def to_s
48
- "per:#{@per}, stack:#{@stack}"
49
- end
50
- end
51
-
52
- # @return [Array<Item>] 月の補正値
53
- # @note キーは複合キーであり、以下のパターンに対応する
54
- # * 進退
55
- # * forward: 進(遠地点より数える)
56
- # * back: 退(近地点より数える)
57
- # * 入暦(1-14)
58
- # * 小余(0-8400)
59
- LIST = {
60
- forward_01_0000_8400: Item.new(per: +830, stack: 0),
61
- forward_02_0000_8400: Item.new(per: +726, stack: +830),
62
- forward_03_0000_8400: Item.new(per: +606, stack: +1556),
63
- forward_04_0000_8400: Item.new(per: +471, stack: +2162),
64
- forward_05_0000_8400: Item.new(per: +337, stack: +2633),
65
- forward_06_0000_8400: Item.new(per: +202, stack: +2970),
66
- forward_07_0000_7465: Item.new(per: +53, stack: +3172),
67
- forward_07_7465_8400: Item.new(per: -7, stack: +3225), # +3172 + 53(初益)
68
- forward_08_0000_8400: Item.new(per: -82, stack: +3218),
69
- forward_09_0000_8400: Item.new(per: -224, stack: +3136),
70
- forward_10_0000_8400: Item.new(per: -366, stack: +2912),
71
- forward_11_0000_8400: Item.new(per: -509, stack: +2546),
72
- forward_12_0000_8400: Item.new(per: -643, stack: +2037),
73
- forward_13_0000_8400: Item.new(per: -748, stack: +1394),
74
- forward_14_0000_6529: Item.new(per: -646, stack: +646), # 14日の小余は常に6529以下
75
- back_01_0000_8400: Item.new(per: -830, stack: 0),
76
- back_02_0000_8400: Item.new(per: -726, stack: -830),
77
- back_03_0000_8400: Item.new(per: -598, stack: -1556),
78
- back_04_0000_8400: Item.new(per: -464, stack: -2154),
79
- back_05_0000_8400: Item.new(per: -329, stack: -2618),
80
- back_06_0000_8400: Item.new(per: -195, stack: -2947),
81
- back_07_0000_7465: Item.new(per: -53, stack: -3142),
82
- back_07_7465_8400: Item.new(per: +7, stack: -3195), # -3142 - 53(初益)
83
- back_08_0000_8400: Item.new(per: +82, stack: -3188),
84
- back_09_0000_8400: Item.new(per: +225, stack: -3106),
85
- back_10_0000_8400: Item.new(per: +366, stack: -2881),
86
- back_11_0000_8400: Item.new(per: +501, stack: -2515),
87
- back_12_0000_8400: Item.new(per: +628, stack: -2014),
88
- back_13_0000_8400: Item.new(per: +740, stack: -1386),
89
- back_14_0000_6529: Item.new(per: +646, stack: -646) # 14日の小余は常に6529以下
90
- }.freeze
91
- end
92
-
93
- #
94
- # 月の運行による補正値を算出する
95
- #
96
- # @param [Remainder] remainder_month 月の大余小余
97
- # @param [True, False] is_forward 進(遠地点より数える)/退(近地点より数える)
98
- #
99
- # @return [Integer] 補正値
100
- #
101
- def self.calc_moon_orbit_value(remainder_month:, is_forward:)
102
- valid?(remainder: remainder_month)
103
-
104
- day, minute = make_calculable_remainder_value(remainder: remainder_month)
105
-
106
- # 引き当て
107
- adjustment, diff, minute = specify_moon_adjustment(
108
- is_forward: is_forward, day: day, minute: minute
109
- )
110
- day = make_cumulative_value_for_days(per: adjustment.per,
111
- denominator: diff, minute: minute)
112
-
113
- adjustment.stack + day
114
- end
115
-
116
- #
117
- # 大余小余を検証する
118
- #
119
- # @param [Remainder] remainder 大余小余
120
- #
121
- # @return [True] 正しい(月の位相計算に使う大余小余)
122
- # @return [True] 正しくない
123
- #
124
- def self.valid?(remainder:)
125
- return if remainder.is_a?(Cycle::LunarRemainder)
126
-
127
- raise ArgumentError, "unmatch parameter type: #{remainder.class}"
128
- end
129
- private_class_method :valid?
130
-
131
- #
132
- # 大余小余を計算可能な値にする
133
- # @note 大余の秒(second)は使わない
134
- #
135
- # @param [LunarRemainder] remainder 大余小余
136
- #
137
- # @return [Integer] 大余
138
- # @return [Integer] 小余
139
- #
140
- def self.make_calculable_remainder_value(remainder:)
141
- day = remainder.day
142
- minute = remainder.minute + (remainder.second / 100)
143
- minute = minute.floor
144
-
145
- [day, minute]
146
- end
147
- private_class_method :make_calculable_remainder_value
148
-
149
- # :reek:TooManyStatements { max_statements: 9 }
150
-
151
- #
152
- # 累計値(大余)を作成する
153
- #
154
- # @param [Integer] per 入暦(1-14)
155
- # @param [Integer] denominator 小余の分母
156
- # @param [Integer] minute 小余
157
- #
158
- # @return [Integer] 累計値(大余)
159
- #
160
- def self.make_cumulative_value_for_days(per:, denominator:, minute:)
161
- remainder_minute = (per * minute).to_f
162
- day = remainder_minute / denominator
163
- # 切り捨て(プラスマイナスに関わらず小数点以下切り捨て)
164
- day = day.negative? ? day.ceil : day.floor
165
- sign = remainder_minute.negative? ? -1 : 1
166
- remainder_day = (sign * remainder_minute) % denominator
167
- # 四捨五入(8400ならその半分の4200以上を繰り上げる)
168
- day += sign if remainder_day >= (denominator / 2)
169
-
170
- day
171
- end
172
- private_class_method :make_cumulative_value_for_days
173
-
174
- # :reek:TooManyStatements { max_statements: 9 }
175
-
176
- #
177
- # 月軌道の補正に必要な基本値を引き当てる
178
- #
179
- # @note 戻り値は calc_moon_orbit_value で使用する
180
- #
181
- # @param [True, False] is_forward 進(遠地点より数える)/退(近地点より数える)
182
- # @param [Integer] day 大余
183
- # @param [Integer] minute 小余
184
- #
185
- # @return [Adjustment::Item] 補正値
186
- # @return [Integer] (小余を処理する時の)分母
187
- # @return [Integer] 小余の下げ幅
188
- #
189
- def self.specify_moon_adjustment(is_forward:, day:, minute:)
190
- prefix = { true => 'forward', false => 'back' }[is_forward]
191
-
192
- targets = Adjustment::LIST.select \
193
- { |key, _| key.match(/^#{prefix}_#{format('%<day>02d', day: day)}_.*/) }
194
-
195
- targets.each do |key, value|
196
- # NOTE: 境界値は上から順に引き当てた方を返す(7日の境界値7465は上のキーで返す)
197
- matched, diff = \
198
- extract_data_from_moon_adjustment_key(key, minute)
199
- # 小余の下げ幅
200
- calc_minute = (day == 7 && minute > 7465 ? minute - 7465 : minute)
201
- return value, diff, calc_minute if matched
202
- end
203
-
204
- [nil, nil, nil]
205
- end
206
- private_class_method :specify_moon_adjustment
207
-
208
- #
209
- # 補正値を引き当てる
210
- #
211
- # @param [String] key 補正値のキー
212
- # @param [Integer] minute 小余
213
- #
214
- # @return [Adjustment::Item] 補正値
215
- # @return [Integer] (小余を処理する時の)分母
216
- #
217
- def self.extract_data_from_moon_adjustment_key(key, minute)
218
- matched = key.match(/([0-9]{4})_([0-9]{4})$/)
219
- start = matched[1].to_i
220
- finish = matched[2].to_i
221
-
222
- matched = minute >= start && minute <= finish
223
- [matched, (finish - start)]
224
- end
225
- private_class_method :extract_data_from_moon_adjustment_key
226
-
227
- # :reek:ControlParameter and :reek:BooleanParameter
228
- # :reek:LongParameterList { max_params: 4 }
229
-
230
- #
231
- # 月地点を計算する
232
- #
233
- # @param [LunarRemainder] remainder 初回(昨年冬至), 前回計算結果(入暦)
234
- # @param [Integer] western_year 西暦年
235
- # @param [True, False] is_forward 進(遠地点より数える)/退(近地点より数える)
236
- # @param [True, False] first 初回計算, 次回以降計算
237
- #
238
- # @return [LunarRemainder] 入暦
239
- # @return [True] 進(遠地点より数える)
240
- # @return [False] 退(近地点より数える)
241
- #
242
- def self.calc_moon_point(remainder:, western_year:,
243
- is_forward: true, first: true)
244
- if first
245
- return calc_first_moon_point(winter_solstice_age: remainder,
246
- western_year: western_year)
247
- end
248
- calc_following_moon_point(remainder: remainder, is_forward: is_forward)
249
- end
250
-
251
- # :reek:TooManyStatements { max_statements: 7 }
252
-
253
- #
254
- # 入暦(月の遠地点から数えた日数/近地点から数えた日数)を求める
255
- #
256
- # 天正冬至(入暦前回未計算)を求める
257
- #
258
- # @param [Remainder] winter_solstice_age 天正閏余
259
- # @param [Integer] western_year 西暦年
260
- #
261
- # @return [LunarRemainder] 入暦
262
- # @return [True] 進(遠地点より数える)
263
- # @return [False] 退(近地点より数える)
264
- #
265
- def self.calc_first_moon_point(winter_solstice_age:, western_year:)
266
- # 積年の開始から対象年までの年数
267
- total_year = \
268
- WinterSolstice::TOTAL_YEAR + western_year - WinterSolstice::BEGIN_YEAR
269
-
270
- # 通積分 - 天正閏余
271
- total_day = \
272
- total_year * WinterSolstice::YEAR - winter_solstice_age.to_minute
273
-
274
- remainder_month = \
275
- Cycle::LunarRemainder.new(total: (total_day % ANOMALISTIC_MONTH))
276
-
277
- remainder_month, is_forward = decrease_moon_point(
278
- remainder_month: remainder_month,
279
- remainder_limit: HALF_ANOMALISTIC_MONTH, is_forward: true
280
- )
281
-
282
- remainder_month.add!(Cycle::Remainder.new(day: 1, minute: 0, second: 0))
283
-
284
- [remainder_month, is_forward]
285
- end
286
- private_class_method :calc_first_moon_point
287
-
288
- #
289
- # 入暦(月の遠地点から数えた日数/近地点から数えた日数)を求める
290
- #
291
- # 前回計算結果を補正する
292
- #
293
- # @param [LunarRemainder] remainder 前回計算結果(入暦)
294
- # @param [True, False] is_forward 進(遠地点より数える)/退(近地点より数える)
295
- #
296
- # @return [LunarRemainder] 入暦
297
- # @return [True] 進(遠地点より数える)
298
- # @return [False] 退(近地点より数える)
299
- #
300
- def self.calc_following_moon_point(remainder:, is_forward:)
301
- # 前回計算結果を引き継いた場合、暦中日ではなく損益眺朒(ちょうじく)数の上限とする
302
- remainder_month, is_forward = \
303
- decrease_moon_point(
304
- remainder_month: remainder,
305
- remainder_limit: Cycle::Remainder.new(day: 14, minute: 6529, second: 0),
306
- is_forward: is_forward
307
- )
308
-
309
- [remainder_month, is_forward]
310
- end
311
- private_class_method :calc_following_moon_point
312
-
313
- #
314
- # 月地点を減算する
315
- #
316
- # @param [LunarRemainder] remainder_month 大余小余
317
- # @param [Remainder] remainder_limit 大余小余の上限(最大の入暦)
318
- # @param [True, False] is_forward 進(遠地点より数える)/退(近地点より数える)
319
- #
320
- # @return [LunarRemainder] 大余小余の減算結果(上限値超えした場合)
321
- # @return [True] 進(遠地点より数える)
322
- # @return [False] 退(近地点より数える)
323
- #
324
- def self.decrease_moon_point(remainder_month:, remainder_limit:, is_forward:)
325
- return remainder_month, is_forward if remainder_month < remainder_limit
326
-
327
- [remainder_month.sub(HALF_ANOMALISTIC_MONTH), !is_forward]
328
- end
329
- private_class_method :decrease_moon_point
330
- end
331
- end
332
- end