zakuro 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|