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