zakuro 0.0.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.
- checksums.yaml +7 -0
- data/.editorconfig +9 -0
- data/.gitignore +69 -0
- data/.rspec +3 -0
- data/.rubocop.yml +14 -0
- data/.travis.yml +6 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +20 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/images/12/346/234/210/344/273/245/351/231/215/343/201/256/345/205/245/345/256/232/346/260/227.png +0 -0
- data/images/12/346/234/210/344/273/245/351/231/215/343/201/256/346/234/210/343/201/256/351/200/262/351/200/200.png +0 -0
- data/images/source/description.numbers +0 -0
- data/images//345/205/245/345/256/232/346/260/227/343/201/256/350/265/267/347/256/227.png +0 -0
- data/images//345/220/204/346/234/210/343/201/256/346/261/202/343/202/201/346/226/271.png +0 -0
- data/images//345/244/252/351/231/275/343/201/250/346/234/210.png +0 -0
- data/lib/zakuro.rb +9 -0
- data/lib/zakuro/condition.rb +239 -0
- data/lib/zakuro/cycle/abstract_remainder.rb +457 -0
- data/lib/zakuro/cycle/zodiac.rb +103 -0
- data/lib/zakuro/era/gengou/set-001-until-south.yaml +375 -0
- data/lib/zakuro/era/gengou/set-002-from-north.yaml +166 -0
- data/lib/zakuro/era/gengou/set-003-modern.yaml +12 -0
- data/lib/zakuro/era/japan.rb +630 -0
- data/lib/zakuro/era/western.rb +412 -0
- data/lib/zakuro/merchant.rb +57 -0
- data/lib/zakuro/output/error.rb +10 -0
- data/lib/zakuro/output/logger.rb +64 -0
- data/lib/zakuro/output/response.rb +170 -0
- data/lib/zakuro/output/result.rb +219 -0
- data/lib/zakuro/output/stringifier.rb +62 -0
- data/lib/zakuro/version.rb +7 -0
- data/lib/zakuro/version/abstract_version.rb +29 -0
- data/lib/zakuro/version/genka/genka.rb +19 -0
- data/lib/zakuro/version/gihou/gihou.rb +19 -0
- data/lib/zakuro/version/gregorio/gregorio.rb +19 -0
- data/lib/zakuro/version/houryaku/houryaku.rb +19 -0
- data/lib/zakuro/version/joukyou/joukyou.rb +19 -0
- data/lib/zakuro/version/kansei/kansei.rb +19 -0
- data/lib/zakuro/version/senmyou/README.md +586 -0
- data/lib/zakuro/version/senmyou/base/era.rb +81 -0
- data/lib/zakuro/version/senmyou/base/gengou.rb +210 -0
- data/lib/zakuro/version/senmyou/base/remainder.rb +60 -0
- data/lib/zakuro/version/senmyou/base/solar_term.rb +66 -0
- data/lib/zakuro/version/senmyou/base/year.rb +58 -0
- data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +220 -0
- data/lib/zakuro/version/senmyou/monthly/month.rb +112 -0
- data/lib/zakuro/version/senmyou/senmyou.rb +34 -0
- data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +332 -0
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +192 -0
- data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +398 -0
- data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +106 -0
- data/lib/zakuro/version/senmyou/summary/annual_data.rb +186 -0
- data/lib/zakuro/version/senmyou/summary/gengou_data.rb +294 -0
- data/lib/zakuro/version/taien/taien.rb +19 -0
- data/lib/zakuro/version/tenpou/tenpou.rb +19 -0
- data/lib/zakuro/version_factory.rb +59 -0
- data/zakuro.gemspec +31 -0
- metadata +106 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../output/logger'
|
4
|
+
|
5
|
+
require_relative '../stella/winter_solstice'
|
6
|
+
|
7
|
+
# :nodoc:
|
8
|
+
module Zakuro
|
9
|
+
# :nodoc:
|
10
|
+
module Senmyou
|
11
|
+
# :reek:TooManyStatements { max_statements: 7 }
|
12
|
+
# :reek:TooManyInstanceVariables { max_instance_variables: 7 }
|
13
|
+
|
14
|
+
#
|
15
|
+
# LunarPhase 月の位相
|
16
|
+
#
|
17
|
+
class LunarPhase
|
18
|
+
#
|
19
|
+
# QuarterMoon 弦
|
20
|
+
#
|
21
|
+
module QuarterMoon
|
22
|
+
# @return [Remainder] 弦(1分=8秒)
|
23
|
+
DEFAULT = Remainder.new(day: 7, minute: 3214, second: 2)
|
24
|
+
# @return [Remainder] 弦(1分=100秒)
|
25
|
+
BASE_HUNDRED = LunarRemainder.new(day: 7, minute: 3214, second: 25)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Logger] ロガー
|
29
|
+
LOGGER = Logger.new(location: 'lunar_phase')
|
30
|
+
|
31
|
+
# @return [Array<String>] 月内の弦
|
32
|
+
PHASE_INDEXES = %w[朔日 上弦 望月 下弦].freeze
|
33
|
+
|
34
|
+
# @return [Integer] 西暦年
|
35
|
+
attr_reader :western_year
|
36
|
+
# @return [Remainder]] 経
|
37
|
+
attr_reader :average_remainder
|
38
|
+
# @return [True] 初回計算
|
39
|
+
# @return [False] 次回以降計算
|
40
|
+
attr_reader :first
|
41
|
+
# @return [SolarTerm] 二十四節気(入定気)
|
42
|
+
attr_reader :solar_term
|
43
|
+
# @return [Remainder] 入暦
|
44
|
+
attr_reader :moon_remainder
|
45
|
+
# @return [True] 進(遠地点より数える)
|
46
|
+
# @return [False] 退(近地点より数える)
|
47
|
+
attr_reader :is_forward
|
48
|
+
# @return [Integer] 弦
|
49
|
+
attr_reader :phase_index
|
50
|
+
|
51
|
+
#
|
52
|
+
# 初期化
|
53
|
+
#
|
54
|
+
# @param [Integer] western_year 西暦年
|
55
|
+
#
|
56
|
+
def initialize(western_year:)
|
57
|
+
@western_year = western_year
|
58
|
+
# 経
|
59
|
+
@average_remainder = WinterSolstice.calc_averaged_last_november_1st(
|
60
|
+
western_year: @western_year
|
61
|
+
)
|
62
|
+
# 天正冬至
|
63
|
+
winter_solstice_age = \
|
64
|
+
WinterSolstice.calc_moon_age(western_year: @western_year)
|
65
|
+
# 入定気
|
66
|
+
@solar_term = SolarTerm.new(remainder: winter_solstice_age)
|
67
|
+
# 入暦
|
68
|
+
@moon_remainder = LunarRemainder.new(total: 0).add!(winter_solstice_age)
|
69
|
+
|
70
|
+
@is_forward = false
|
71
|
+
@first = true
|
72
|
+
|
73
|
+
# 弦
|
74
|
+
@phase_index = 0
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# 次の弦に進める
|
79
|
+
#
|
80
|
+
# @return [Remainder] 定朔
|
81
|
+
#
|
82
|
+
def next_phase
|
83
|
+
adjusted = current_remainder
|
84
|
+
|
85
|
+
@first = false if @first
|
86
|
+
|
87
|
+
add_quarter_moon_size
|
88
|
+
|
89
|
+
adjusted
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# 次の月に進める
|
94
|
+
# @note 進めた後の月の定朔ではなく、当月のものを返却する
|
95
|
+
#
|
96
|
+
# @return [Remainder] 当月初の定朔
|
97
|
+
#
|
98
|
+
def next_month
|
99
|
+
result = nil
|
100
|
+
PHASE_INDEXES.each_with_index do |_phase, index|
|
101
|
+
adjust = next_phase
|
102
|
+
result = adjust if index.zero?
|
103
|
+
end
|
104
|
+
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
#
|
111
|
+
# 次の弦に進める
|
112
|
+
#
|
113
|
+
# @return [Integer] 弦
|
114
|
+
#
|
115
|
+
def next_phase_index
|
116
|
+
@phase_index += 1
|
117
|
+
@phase_index = 0 if @phase_index >= PHASE_INDEXES.size
|
118
|
+
@phase_index
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# 朔月(月初)かを確認する
|
123
|
+
#
|
124
|
+
# @return [True] 朔月である
|
125
|
+
# @return [False] 朔月ではない
|
126
|
+
#
|
127
|
+
def first_phase?
|
128
|
+
@phase_index.zero?
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# 朔月のみログ出力する
|
133
|
+
#
|
134
|
+
# @param [String] messages メッセージ(可変長)
|
135
|
+
#
|
136
|
+
def debug(*messages)
|
137
|
+
return unless first_phase?
|
138
|
+
|
139
|
+
LOGGER.debug(*messages)
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# 現在の定朔を取得する
|
144
|
+
#
|
145
|
+
# @return [Remainder] 定朔
|
146
|
+
#
|
147
|
+
def current_remainder
|
148
|
+
debug('@average_remainder.format:' + @average_remainder.format)
|
149
|
+
|
150
|
+
sum = correction_value
|
151
|
+
adjusted = @average_remainder.add(
|
152
|
+
Remainder.new(day: 0, minute: sum, second: 0)
|
153
|
+
)
|
154
|
+
adjusted.up_on_new_moon!
|
155
|
+
|
156
|
+
debug("result: #{adjusted.format}")
|
157
|
+
|
158
|
+
adjusted
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# 補正値を得る
|
163
|
+
#
|
164
|
+
# @return [Integer] 補正値
|
165
|
+
#
|
166
|
+
def correction_value
|
167
|
+
sun = correction_solar_value
|
168
|
+
moon = correction_moon_value
|
169
|
+
|
170
|
+
sum = sun + moon
|
171
|
+
|
172
|
+
debug("sun: #{sun}", "moon: #{moon}", "sun + moon : #{sum}")
|
173
|
+
|
174
|
+
sum
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
# 太陽運動の補正値を得る
|
179
|
+
#
|
180
|
+
# @return [Integer] 太陽運動の補正値
|
181
|
+
#
|
182
|
+
def correction_solar_value
|
183
|
+
@solar_term = SolarOrbit.calc_solar_term_by_remainder(
|
184
|
+
solar_term: @solar_term
|
185
|
+
)
|
186
|
+
debug("@solar_term.remainder: #{@solar_term.remainder.format(form: '%d-%d.%d')}")
|
187
|
+
debug("@solar_term.index: #{@solar_term.index}")
|
188
|
+
|
189
|
+
SolarOrbit.calc_sun_orbit_value(solar_term: @solar_term)
|
190
|
+
end
|
191
|
+
|
192
|
+
#
|
193
|
+
# 月運動の補正値を得る
|
194
|
+
#
|
195
|
+
# @return [Integer] 月運動の補正値
|
196
|
+
#
|
197
|
+
def correction_moon_value
|
198
|
+
@moon_remainder, @is_forward = \
|
199
|
+
LunarOrbit.calc_moon_point(remainder: @moon_remainder,
|
200
|
+
western_year: @western_year,
|
201
|
+
is_forward: @is_forward,
|
202
|
+
first: @first)
|
203
|
+
|
204
|
+
debug("@moon_remainder.format: #{@moon_remainder.format}")
|
205
|
+
debug("@is_forward: #{@is_forward}")
|
206
|
+
|
207
|
+
LunarOrbit.calc_moon_orbit_value(remainder_month: @moon_remainder,
|
208
|
+
is_forward: @is_forward)
|
209
|
+
end
|
210
|
+
|
211
|
+
def add_quarter_moon_size
|
212
|
+
@average_remainder.add!(QuarterMoon::DEFAULT)
|
213
|
+
@solar_term.remainder.add!(QuarterMoon::DEFAULT)
|
214
|
+
@moon_remainder.add!(QuarterMoon::BASE_HUNDRED)
|
215
|
+
|
216
|
+
next_phase_index
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nodoc:
|
4
|
+
module Zakuro
|
5
|
+
# :nodoc:
|
6
|
+
module Senmyou
|
7
|
+
#
|
8
|
+
# Month 月情報
|
9
|
+
#
|
10
|
+
class Month
|
11
|
+
# @return [True] 昨年の月
|
12
|
+
# @return [False] 今年の月
|
13
|
+
# @note 冬至基準で1年データを作成するため昨年の11月-12月である可能性がある
|
14
|
+
attr_accessor :is_last_year
|
15
|
+
# @return [True] 大の月(30日)
|
16
|
+
# @return [False] 小の月(29日)
|
17
|
+
attr_accessor :is_many_days
|
18
|
+
# @return [Integer] 月(xx月のxx)
|
19
|
+
attr_accessor :number
|
20
|
+
# @return [True] 閏月
|
21
|
+
# @return [False] 平月
|
22
|
+
attr_accessor :leaped
|
23
|
+
# @return [SolarTerm] 二十四節気(中気)
|
24
|
+
attr_accessor :even_term
|
25
|
+
# @return [SolarTerm] 二十四節気(節気)
|
26
|
+
attr_accessor :odd_term
|
27
|
+
# @return [Remainder] 月初日の大余小余
|
28
|
+
attr_reader :remainder
|
29
|
+
# @return [String] 月齢(朔月、上弦、望月、下弦)
|
30
|
+
attr_reader :phase_index
|
31
|
+
|
32
|
+
# rubocop:disable Metrics/ParameterLists
|
33
|
+
# :reek:BooleanParametere
|
34
|
+
|
35
|
+
#
|
36
|
+
# 初期化
|
37
|
+
#
|
38
|
+
# @param [True, False] is_last_year 昨年の月/今年の月
|
39
|
+
# @param [Integer] number 月(xx月のxx)
|
40
|
+
# @param [True, False] is_many_days 大の月(30日)/小の月(29日)
|
41
|
+
# @param [True, False] leaped 閏月/平月
|
42
|
+
# @param [Remainder] remainder 月初日の大余小余
|
43
|
+
# @param [String] phase_index 月齢(朔月、上弦、望月、下弦)
|
44
|
+
# @param [SolarTerm] even_term 二十四節気(中気)
|
45
|
+
# @param [SolarTerm] odd_term 二十四節気(節気)
|
46
|
+
#
|
47
|
+
def initialize(is_last_year: -1, number: -1, is_many_days: false,
|
48
|
+
leaped: false, remainder: Remainder.new, phase_index: -1,
|
49
|
+
even_term: SolarTerm.new, odd_term: SolarTerm.new)
|
50
|
+
# 年
|
51
|
+
@is_last_year = is_last_year
|
52
|
+
# 月の大小
|
53
|
+
@is_many_days = is_many_days
|
54
|
+
# 月
|
55
|
+
@number = number
|
56
|
+
# 閏
|
57
|
+
@leaped = leaped
|
58
|
+
# 日
|
59
|
+
@remainder = remainder
|
60
|
+
# 月齢(朔月、上弦、望月、下弦)
|
61
|
+
@phase_index = phase_index
|
62
|
+
# 中気(二十四節気)
|
63
|
+
@even_term = even_term
|
64
|
+
# 節気(二十四節気)
|
65
|
+
@odd_term = odd_term
|
66
|
+
end
|
67
|
+
# rubocop:enable Metrics/ParameterLists
|
68
|
+
|
69
|
+
#
|
70
|
+
# 月の日数を返す
|
71
|
+
#
|
72
|
+
# @return [Integer] 日数
|
73
|
+
#
|
74
|
+
def days
|
75
|
+
@is_many_days ? 30 : 29
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# 月の名前(大小)を返す
|
80
|
+
#
|
81
|
+
# @return [String] 月の名前(大小)
|
82
|
+
#
|
83
|
+
def days_name
|
84
|
+
@is_many_days ? '大' : '小'
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# 同一の月情報かを検証する
|
89
|
+
#
|
90
|
+
# @param [Month] other 他の月情報
|
91
|
+
#
|
92
|
+
# @return [True] 同一の月
|
93
|
+
# @return [False] 異なる月
|
94
|
+
#
|
95
|
+
def same?(other:)
|
96
|
+
@number == other.number && @leaped == other.leaped
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# 文字化する
|
101
|
+
#
|
102
|
+
# @return [String] 文字
|
103
|
+
#
|
104
|
+
def to_s
|
105
|
+
"is_last_year: #{@is_last_year}, number: #{@number}, leaped: #{@leaped}, " \
|
106
|
+
"remainder: #{@remainder.format}, phase_index: #{@phase_index}, " \
|
107
|
+
"even_term: #{@even_term.remainder.format}: #{@even_term.index}, " \
|
108
|
+
"odd_term: #{@odd_term.remainder.format}: #{@odd_term.index}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
require_relative '../abstract_version'
|
5
|
+
require_relative '../../era/western'
|
6
|
+
require_relative 'summary/gengou_data'
|
7
|
+
|
8
|
+
# :nodoc:
|
9
|
+
module Zakuro
|
10
|
+
#
|
11
|
+
# Senmyou 宣明暦
|
12
|
+
#
|
13
|
+
module Senmyou
|
14
|
+
#
|
15
|
+
# Gateway アクセサメソッド群
|
16
|
+
#
|
17
|
+
class Gateway < AbstractVersion
|
18
|
+
# @return [True] リリースあり
|
19
|
+
RELEASE = true
|
20
|
+
|
21
|
+
#
|
22
|
+
# 西暦日から和暦日に変換する
|
23
|
+
#
|
24
|
+
# @param [Date] western_date 西暦日
|
25
|
+
#
|
26
|
+
# @return [Result::SingleDay] 和暦日
|
27
|
+
#
|
28
|
+
def self.to_japan_date(western_date:)
|
29
|
+
date = Western::Calendar.create(date: western_date)
|
30
|
+
GengouData.get_ancient_date(date: date)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,332 @@
|
|
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
|
+
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?(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
|
+
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!(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: 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
|