zakuro 0.0.2 → 0.1.3
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 +4 -4
- data/.rubocop.yml +3 -0
- data/README.md +102 -42
- data/doc/operation.md +25 -0
- data/doc/operation/csv/month.csv +202 -0
- data/doc/operation/operation.xlsx +0 -0
- data/doc/operation/transfer.rb +77 -0
- data/lib/zakuro/calculation/base/multi_gengou.rb +101 -0
- data/lib/zakuro/calculation/base/multi_gengou_roller.rb +218 -0
- data/lib/zakuro/calculation/base/year.rb +107 -0
- data/lib/zakuro/calculation/cycle/abstract_remainder.rb +459 -0
- data/lib/zakuro/calculation/cycle/abstract_solar_term.rb +151 -0
- data/lib/zakuro/calculation/cycle/zodiac.rb +106 -0
- data/lib/zakuro/calculation/monthly/first_day.rb +45 -0
- data/lib/zakuro/calculation/monthly/initialized_month.rb +120 -0
- data/lib/zakuro/calculation/monthly/month.rb +184 -0
- data/lib/zakuro/calculation/monthly/month_label.rb +88 -0
- data/lib/zakuro/calculation/monthly/operated_month.rb +201 -0
- data/lib/zakuro/calculation/range/full_range.rb +210 -0
- data/lib/zakuro/calculation/range/operated_range.rb +134 -0
- data/lib/zakuro/calculation/range/operated_solar_terms.rb +201 -0
- data/lib/zakuro/calculation/range/transfer/western_date_allocation.rb +76 -0
- data/lib/zakuro/calculation/range/transfer/year_boundary.rb +142 -0
- data/lib/zakuro/calculation/specifier/single_day.rb +109 -0
- data/lib/zakuro/calculation/summary/single.rb +129 -0
- data/lib/zakuro/condition.rb +17 -13
- data/lib/zakuro/era/japan/gengou.rb +106 -0
- data/lib/zakuro/era/japan/gengou/parser.rb +167 -0
- data/lib/zakuro/era/japan/gengou/type.rb +178 -0
- data/lib/zakuro/era/japan/gengou/validator.rb +236 -0
- data/lib/zakuro/era/japan/reki.rb +91 -0
- data/lib/zakuro/era/{gengou → japan/yaml}/set-001-until-south.yaml +0 -0
- data/lib/zakuro/era/{gengou → japan/yaml}/set-002-from-north.yaml +0 -0
- data/lib/zakuro/era/{gengou → japan/yaml}/set-003-modern.yaml +1 -1
- data/lib/zakuro/era/western.rb +1 -1
- data/lib/zakuro/merchant.rb +2 -2
- data/lib/zakuro/operation/month/parser.rb +373 -0
- data/lib/zakuro/operation/month/type.rb +453 -0
- data/lib/zakuro/operation/month/validator.rb +802 -0
- data/lib/zakuro/operation/operation.rb +66 -0
- data/lib/zakuro/operation/yaml/month.yaml +6452 -0
- data/lib/zakuro/output/error.rb +7 -4
- data/lib/zakuro/output/logger.rb +50 -47
- data/lib/zakuro/output/response.rb +146 -143
- data/lib/zakuro/result/core.rb +52 -0
- data/lib/zakuro/result/data.rb +187 -0
- data/lib/zakuro/result/operation.rb +114 -0
- data/lib/zakuro/result/result.rb +37 -0
- data/lib/zakuro/{output → tools}/stringifier.rb +16 -9
- data/lib/zakuro/tools/typeof.rb +33 -0
- data/lib/zakuro/version.rb +1 -1
- data/lib/zakuro/version/abstract_version.rb +1 -1
- data/lib/zakuro/version/context.rb +23 -0
- data/lib/zakuro/version/senmyou/cycle/remainder.rb +63 -0
- data/lib/zakuro/version/senmyou/cycle/solar_term.rb +31 -0
- data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +186 -182
- data/lib/zakuro/version/senmyou/range/annual_range.rb +164 -0
- data/lib/zakuro/version/senmyou/senmyou.rb +10 -4
- data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +7 -7
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +103 -138
- data/lib/zakuro/version/senmyou/stella/solar_location.rb +213 -0
- data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +6 -191
- data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +4 -4
- data/lib/zakuro/version/version_class_resolver.rb +62 -0
- data/lib/zakuro/version_factory.rb +3 -3
- metadata +49 -20
- data/lib/zakuro/cycle/abstract_remainder.rb +0 -457
- data/lib/zakuro/cycle/zodiac.rb +0 -103
- data/lib/zakuro/era/japan.rb +0 -660
- data/lib/zakuro/output/result.rb +0 -219
- data/lib/zakuro/version/senmyou/base/era.rb +0 -83
- data/lib/zakuro/version/senmyou/base/multi_gengou.rb +0 -98
- data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +0 -205
- data/lib/zakuro/version/senmyou/base/remainder.rb +0 -60
- data/lib/zakuro/version/senmyou/base/solar_term.rb +0 -66
- data/lib/zakuro/version/senmyou/base/year.rb +0 -104
- data/lib/zakuro/version/senmyou/monthly/month.rb +0 -122
- data/lib/zakuro/version/senmyou/summary/annual_range.rb +0 -186
- data/lib/zakuro/version/senmyou/summary/full_range.rb +0 -216
- data/lib/zakuro/version/senmyou/summary/specifier.rb +0 -100
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../output/logger'
|
4
|
+
require_relative '../cycle/remainder'
|
5
|
+
require_relative '../cycle/solar_term'
|
6
|
+
require_relative '../../../calculation/monthly/initialized_month'
|
7
|
+
require_relative '../monthly/lunar_phase'
|
8
|
+
require_relative '../stella/solar_orbit'
|
9
|
+
require_relative '../stella/solar_average'
|
10
|
+
require_relative '../stella/solar_location'
|
11
|
+
require_relative '../stella/lunar_orbit'
|
12
|
+
|
13
|
+
# :nodoc:
|
14
|
+
module Zakuro
|
15
|
+
# :nodoc:
|
16
|
+
module Senmyou
|
17
|
+
# :nodoc:
|
18
|
+
module Range
|
19
|
+
#
|
20
|
+
# AnnualRange 年間範囲
|
21
|
+
#
|
22
|
+
module AnnualRange
|
23
|
+
# @return [Output::Logger] ロガー
|
24
|
+
LOGGER = Output::Logger.new(location: 'annual_range')
|
25
|
+
|
26
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
27
|
+
|
28
|
+
#
|
29
|
+
# 11月定朔(冬至が含まれる月の1日:補正済)を求める
|
30
|
+
#
|
31
|
+
# @param [Integer] western_year 西暦年
|
32
|
+
#
|
33
|
+
# @return [Remainder] 11月定朔
|
34
|
+
#
|
35
|
+
def self.calc_last_november_1st(western_year:)
|
36
|
+
# 天正閏余
|
37
|
+
winter_solstice_age = \
|
38
|
+
WinterSolstice.calc_moon_age(western_year: western_year)
|
39
|
+
# 11月経朔
|
40
|
+
november_1st = \
|
41
|
+
WinterSolstice.calc_averaged_last_november_1st(western_year: western_year)
|
42
|
+
# 11月定朔
|
43
|
+
|
44
|
+
# 補正
|
45
|
+
correction_value = correction_value_on_last_november_1st(
|
46
|
+
winter_solstice_age: winter_solstice_age,
|
47
|
+
western_year: western_year
|
48
|
+
)
|
49
|
+
|
50
|
+
result = november_1st.add(Cycle::Remainder.new(day: 0, minute: correction_value,
|
51
|
+
second: 0))
|
52
|
+
# 進朔
|
53
|
+
result.up_on_new_moon!
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
58
|
+
|
59
|
+
#
|
60
|
+
# 一覧取得する
|
61
|
+
#
|
62
|
+
# * 対象年に対して、前年11月-当年11月までを出力する
|
63
|
+
# * 対象年(西暦)と計算年(元号x年)の紐付けは行わない
|
64
|
+
#
|
65
|
+
# @param [Integer] western_year 西暦年
|
66
|
+
#
|
67
|
+
# @return [Array<Month>] 1年データ
|
68
|
+
#
|
69
|
+
def self.collect_annual_range_after_last_november_1st(western_year:)
|
70
|
+
annual_range = initialized_annual_range(western_year: western_year)
|
71
|
+
|
72
|
+
apply_big_and_small_of_the_month(annual_range: annual_range)
|
73
|
+
|
74
|
+
solar_average = SolarAverage.new(western_year: western_year)
|
75
|
+
solar_average.set(annual_range: annual_range)
|
76
|
+
|
77
|
+
# 月間隔を取得するためだけの末尾要素を削除
|
78
|
+
annual_range.pop
|
79
|
+
|
80
|
+
initialize_month_label(annual_range: annual_range)
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# 11月定朔の補正値を求める
|
85
|
+
#
|
86
|
+
# @param [Remainder] winter_solstice_age 天正閏余
|
87
|
+
# @param [Integer] western_year 西暦年
|
88
|
+
#
|
89
|
+
# @return [Integer] 補正値
|
90
|
+
#
|
91
|
+
def self.correction_value_on_last_november_1st(winter_solstice_age:, western_year:)
|
92
|
+
# 補正
|
93
|
+
solar_term = Cycle::SolarTerm.new(
|
94
|
+
remainder: winter_solstice_age
|
95
|
+
)
|
96
|
+
solar_term = \
|
97
|
+
SolarLocation.get(
|
98
|
+
solar_term: solar_term
|
99
|
+
)
|
100
|
+
|
101
|
+
moon_remainder, is_forward = LunarOrbit.calc_moon_point(
|
102
|
+
remainder: winter_solstice_age, western_year: western_year
|
103
|
+
)
|
104
|
+
|
105
|
+
SolarOrbit.calc_sun_orbit_value(solar_term: solar_term) +
|
106
|
+
LunarOrbit.calc_moon_orbit_value(remainder_month: moon_remainder,
|
107
|
+
is_forward: is_forward)
|
108
|
+
end
|
109
|
+
private_class_method :correction_value_on_last_november_1st
|
110
|
+
|
111
|
+
#
|
112
|
+
# 1年データを取得する
|
113
|
+
#
|
114
|
+
# @param [Integer] western_year 西暦年
|
115
|
+
#
|
116
|
+
# @return [Array<Month>] 1年データ
|
117
|
+
#
|
118
|
+
def self.initialized_annual_range(western_year:)
|
119
|
+
result = []
|
120
|
+
lunar_phase = Monthly::LunarPhase.new(western_year: western_year)
|
121
|
+
|
122
|
+
# 14ヶ月分を生成する(閏年で最大13ヶ月 + 末月の大小/二十四節気を求めるために必要な月)
|
123
|
+
(0..13).each do |_index|
|
124
|
+
adjusted = lunar_phase.next_month
|
125
|
+
|
126
|
+
result.push(
|
127
|
+
Calculation::Monthly::InitializedMonth.new(
|
128
|
+
month_label: Calculation::Monthly::MonthLabel.new,
|
129
|
+
first_day: Calculation::Monthly::FirstDay.new(remainder: adjusted),
|
130
|
+
phase_index: 0
|
131
|
+
)
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
135
|
+
result
|
136
|
+
end
|
137
|
+
private_class_method :initialized_annual_range
|
138
|
+
|
139
|
+
#
|
140
|
+
# 1年データの各月に月の大小を設定する
|
141
|
+
#
|
142
|
+
# @param [Array<Month>] annual_range 1年データ
|
143
|
+
#
|
144
|
+
def self.apply_big_and_small_of_the_month(annual_range:)
|
145
|
+
# NOTE: 最後の月は処理できない(=計算外の余分な月が最後に必要である)
|
146
|
+
annual_range.each_cons(2) do |(current_month, next_month)|
|
147
|
+
current_month.eval_many_days(next_month_day: next_month.remainder.day)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
private_class_method :apply_big_and_small_of_the_month
|
151
|
+
|
152
|
+
#
|
153
|
+
# 月表示情報を更新する
|
154
|
+
#
|
155
|
+
# @param [Array<Month>] annual_range 1年データ
|
156
|
+
#
|
157
|
+
def self.initialize_month_label(annual_range:)
|
158
|
+
annual_range.each(&:rename_month_label_by_solar_term)
|
159
|
+
end
|
160
|
+
private_class_method :initialize_month_label
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'date'
|
4
|
-
require_relative '../abstract_version'
|
5
4
|
require_relative '../../era/western'
|
6
|
-
require_relative '
|
5
|
+
require_relative '../abstract_version'
|
6
|
+
require_relative '../context'
|
7
|
+
require_relative '../../calculation/summary/single'
|
7
8
|
|
8
9
|
# :nodoc:
|
9
10
|
module Zakuro
|
@@ -18,16 +19,21 @@ module Zakuro
|
|
18
19
|
# @return [True] リリースあり
|
19
20
|
RELEASE = true
|
20
21
|
|
22
|
+
# @return [String] 暦クラス名
|
23
|
+
VERSION_NAME = 'Senmyou'
|
24
|
+
|
21
25
|
#
|
22
26
|
# 西暦日から和暦日に変換する
|
23
27
|
#
|
24
28
|
# @param [Date] western_date 西暦日
|
25
29
|
#
|
26
|
-
# @return [Result::
|
30
|
+
# @return [Result::Single] 和暦日
|
27
31
|
#
|
28
32
|
def self.to_japan_date(western_date:)
|
29
33
|
date = Western::Calendar.create(date: western_date)
|
30
|
-
|
34
|
+
|
35
|
+
context = Context.new(version_name: VERSION_NAME)
|
36
|
+
Calculation::Summary::Single.get(context: context, date: date)
|
31
37
|
end
|
32
38
|
end
|
33
39
|
end
|
@@ -13,7 +13,7 @@ module Zakuro
|
|
13
13
|
# @return [Integer] 暦中日
|
14
14
|
# @note ANOMALISTIC_MONTH の半分に相当する
|
15
15
|
HALF_ANOMALISTIC_MONTH = \
|
16
|
-
LunarRemainder.new(day: 13, minute: 6529, second: 9.5)
|
16
|
+
Cycle::LunarRemainder.new(day: 13, minute: 6529, second: 9.5)
|
17
17
|
|
18
18
|
#
|
19
19
|
# Adjustment 補正値情報
|
@@ -122,7 +122,7 @@ module Zakuro
|
|
122
122
|
# @return [True] 正しくない
|
123
123
|
#
|
124
124
|
def self.valid?(remainder:)
|
125
|
-
return if remainder.is_a?(LunarRemainder)
|
125
|
+
return if remainder.is_a?(Cycle::LunarRemainder)
|
126
126
|
|
127
127
|
raise ArgumentError, "unmatch parameter type: #{remainder.class}"
|
128
128
|
end
|
@@ -193,7 +193,7 @@ module Zakuro
|
|
193
193
|
{ |key, _| key.match(/^#{prefix}_#{format('%<day>02d', day: day)}_.*/) }
|
194
194
|
|
195
195
|
targets.each do |key, value|
|
196
|
-
# NOTE 境界値は上から順に引き当てた方を返す(7日の境界値7465は上のキーで返す)
|
196
|
+
# NOTE: 境界値は上から順に引き当てた方を返す(7日の境界値7465は上のキーで返す)
|
197
197
|
matched, diff = \
|
198
198
|
extract_data_from_moon_adjustment_key(key, minute)
|
199
199
|
# 小余の下げ幅
|
@@ -255,7 +255,7 @@ module Zakuro
|
|
255
255
|
#
|
256
256
|
# 天正冬至(入暦前回未計算)を求める
|
257
257
|
#
|
258
|
-
# @param [Remainder] winter_solstice_age
|
258
|
+
# @param [Remainder] winter_solstice_age 天正閏余
|
259
259
|
# @param [Integer] western_year 西暦年
|
260
260
|
#
|
261
261
|
# @return [LunarRemainder] 入暦
|
@@ -272,14 +272,14 @@ module Zakuro
|
|
272
272
|
total_year * WinterSolstice::YEAR - winter_solstice_age.to_minute
|
273
273
|
|
274
274
|
remainder_month = \
|
275
|
-
LunarRemainder.new(total: (total_day % ANOMALISTIC_MONTH))
|
275
|
+
Cycle::LunarRemainder.new(total: (total_day % ANOMALISTIC_MONTH))
|
276
276
|
|
277
277
|
remainder_month, is_forward = decrease_moon_point(
|
278
278
|
remainder_month: remainder_month,
|
279
279
|
remainder_limit: HALF_ANOMALISTIC_MONTH, is_forward: true
|
280
280
|
)
|
281
281
|
|
282
|
-
remainder_month.add!(Remainder.new(day: 1, minute: 0, second: 0))
|
282
|
+
remainder_month.add!(Cycle::Remainder.new(day: 1, minute: 0, second: 0))
|
283
283
|
|
284
284
|
[remainder_month, is_forward]
|
285
285
|
end
|
@@ -302,7 +302,7 @@ module Zakuro
|
|
302
302
|
remainder_month, is_forward = \
|
303
303
|
decrease_moon_point(
|
304
304
|
remainder_month: remainder,
|
305
|
-
remainder_limit: Remainder.new(day: 14, minute: 6529, second: 0),
|
305
|
+
remainder_limit: Cycle::Remainder.new(day: 14, minute: 6529, second: 0),
|
306
306
|
is_forward: is_forward
|
307
307
|
)
|
308
308
|
|
@@ -7,198 +7,163 @@ module Zakuro
|
|
7
7
|
#
|
8
8
|
# SolarAverage 常気(太陽軌道平均)
|
9
9
|
#
|
10
|
-
|
10
|
+
class SolarAverage
|
11
11
|
# @return [Remainder] 気策(24分の1年)
|
12
|
-
SOLAR_TERM_AVERAGE = Remainder.new(day: 15, minute: 1835, second: 5)
|
13
|
-
|
14
|
-
# :reek:TooManyStatements { max_statements: 6 }
|
12
|
+
SOLAR_TERM_AVERAGE = Cycle::Remainder.new(day: 15, minute: 1835, second: 5)
|
15
13
|
|
16
14
|
#
|
17
|
-
#
|
15
|
+
# 初期化
|
18
16
|
#
|
19
17
|
# @param [Integer] western_year 西暦年
|
20
|
-
# @param [Array<Month>] annual_range 1年データ
|
21
|
-
#
|
22
|
-
# @return [Array<Month>] 1年データ
|
23
18
|
#
|
24
|
-
def
|
25
|
-
|
26
|
-
winter_solstice = WinterSolstice.calc(western_year: western_year)
|
27
|
-
|
28
|
-
# 前年冬至からの二十四節気
|
29
|
-
solar_terms = collect_solar_terms_from_last_winter_solstice(
|
30
|
-
winter_solstice: winter_solstice
|
31
|
-
)
|
32
|
-
|
33
|
-
apply_solar_terms_from_last_winter_solstice(annual_range: annual_range,
|
34
|
-
solar_terms: solar_terms)
|
35
|
-
|
36
|
-
# 前後の二十四節気
|
37
|
-
rest_solar_terms = \
|
38
|
-
collect_solar_terms_before_and_after(solar_terms: solar_terms)
|
39
|
-
|
40
|
-
apply_solar_terms_before_and_after(annual_range: annual_range,
|
41
|
-
rest_solar_terms: rest_solar_terms)
|
42
|
-
|
43
|
-
annual_range
|
19
|
+
def initialize(western_year:)
|
20
|
+
@solar_term = SolarAverage.first_solar_term(western_year: western_year)
|
44
21
|
end
|
45
22
|
|
46
|
-
# :reek:TooManyStatements { max_statements: 6 }
|
47
|
-
|
48
23
|
#
|
49
|
-
#
|
24
|
+
# 冬至から数えた1年データの月ごとに二十四節気を割り当てる
|
50
25
|
#
|
51
|
-
# @param [
|
26
|
+
# @param [Array<Month>] annual_range 1年データ
|
52
27
|
#
|
53
|
-
# @return [Array<
|
28
|
+
# @return [Array<Month>] 1年データ
|
54
29
|
#
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
(
|
59
|
-
|
60
|
-
|
30
|
+
def set(annual_range:)
|
31
|
+
# 次月と比較しながら当月の二十四節気を決める
|
32
|
+
# NOTE: 最後の月は処理できない(=計算外の余分な月が最後に必要である)
|
33
|
+
annual_range.each_cons(2) do |(current_month, next_month)|
|
34
|
+
set_solar_term(
|
35
|
+
current_month: current_month,
|
36
|
+
next_month: next_month
|
37
|
+
)
|
61
38
|
end
|
62
39
|
|
63
|
-
|
40
|
+
annual_range
|
64
41
|
end
|
65
|
-
private_class_method :collect_solar_terms_from_last_winter_solstice
|
66
|
-
|
67
|
-
# :reek:TooManyStatements { max_statements: 9 }
|
68
42
|
|
69
43
|
#
|
70
|
-
#
|
44
|
+
# 計算開始する二十四節気を求める
|
71
45
|
#
|
72
|
-
# @param [
|
73
|
-
# @param [Array<Remainder>] solar_terms 1年データ内の全二十四節気
|
46
|
+
# @param [Integer] western_year 西暦年
|
74
47
|
#
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
month_size = annual_range.size
|
48
|
+
# @return [SolarTerm] 二十四節気
|
49
|
+
#
|
50
|
+
def self.first_solar_term(western_year:)
|
51
|
+
# 天正冬至
|
52
|
+
winter_solstice = WinterSolstice.calc(western_year: western_year)
|
81
53
|
|
82
|
-
|
83
|
-
|
54
|
+
# 二十四節気(冬至)
|
55
|
+
solar_term = Cycle::SolarTerm.new(index: 0, remainder: winter_solstice)
|
84
56
|
|
85
|
-
|
86
|
-
next_month = annual_range[c_idx + 1]
|
87
|
-
solar_term = solar_terms[st_idx]
|
57
|
+
first_solar_term_index = SolarAverage.calc_fist_solar_term_index(western_year: western_year)
|
88
58
|
|
89
|
-
|
90
|
-
|
91
|
-
set_solar_term(month: current_month,
|
92
|
-
solar_term: solar_term, solar_term_index: st_idx)
|
93
|
-
st_idx += 1
|
94
|
-
next
|
95
|
-
end
|
59
|
+
# 対象の二十四節気まで戻す
|
60
|
+
solar_term.prev_by_index(first_solar_term_index)
|
96
61
|
|
97
|
-
|
98
|
-
if current_month.empty_solar_term?
|
99
|
-
st_idx += 1
|
100
|
-
next
|
101
|
-
end
|
102
|
-
|
103
|
-
c_idx += 1
|
104
|
-
end
|
62
|
+
solar_term
|
105
63
|
end
|
106
|
-
private_class_method :apply_solar_terms_from_last_winter_solstice
|
107
64
|
|
108
65
|
#
|
109
|
-
#
|
66
|
+
# 計算開始する二十四節気番号を求める
|
110
67
|
#
|
111
|
-
#
|
68
|
+
# * 前提として入定気は冬至の手前にある
|
69
|
+
# * 例えば、定気が大雪であれば入定気は大雪の範囲内にある
|
70
|
+
# * 入定気は、定気の開始位置に重複しない限り、常に定気より後にある
|
71
|
+
# * 基本的に定気の一つ前から起算すれば、当時から求めた11月(閏10/閏11月)に二十四節気を割り当てられる
|
112
72
|
#
|
113
|
-
# @
|
73
|
+
# @param [Integer] western_year 西暦年
|
74
|
+
#
|
75
|
+
# @return [Integer] 二十四節気番号
|
114
76
|
#
|
115
|
-
def self.
|
116
|
-
|
77
|
+
def self.calc_fist_solar_term_index(western_year:)
|
78
|
+
# 天正閏余
|
79
|
+
winter_solstice_age = \
|
80
|
+
WinterSolstice.calc_moon_age(western_year: western_year)
|
117
81
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
# 当年冬至
|
123
|
-
0 => { index: -2, solar_term: touji },
|
124
|
-
# 当年小寒
|
125
|
-
1 => { index: -2, solar_term: touji.add(SOLAR_TERM_AVERAGE) }
|
126
|
-
}
|
127
|
-
end
|
128
|
-
private_class_method :collect_solar_terms_before_and_after
|
82
|
+
# 入定気を求める
|
83
|
+
solar_location = SolarLocation.get(
|
84
|
+
solar_term: Cycle::SolarTerm.new(remainder: winter_solstice_age)
|
85
|
+
)
|
129
86
|
|
130
|
-
|
87
|
+
solar_term_index = solar_location.index
|
131
88
|
|
132
|
-
|
133
|
-
|
134
|
-
#
|
135
|
-
# @param [Array<Month>] annual_range 1年データ
|
136
|
-
# @param [Hash<Integer, Hash<Symbol, Integer>>, Hash<Integer, Hash<Symbol, Remainder>>]
|
137
|
-
# rest_solar_terms 前後
|
138
|
-
#
|
139
|
-
def self.apply_solar_terms_before_and_after(annual_range:, rest_solar_terms:)
|
140
|
-
rest_solar_terms.each do |key, value|
|
141
|
-
index = value[:index]
|
142
|
-
solar_term = value[:solar_term]
|
143
|
-
data = annual_range[index]
|
144
|
-
next unless in_range_solar_term?(
|
145
|
-
target: solar_term,
|
146
|
-
min: data.remainder, max: annual_range[index + 1].remainder
|
147
|
-
)
|
89
|
+
# 入定気の一つ後の二十四節気まで戻す(ただし11月経朔が二十四節気上にある場合は戻さない)
|
90
|
+
solar_term_index += 1 unless solar_location.remainder == Cycle::Remainder.new(total: 0)
|
148
91
|
|
149
|
-
|
150
|
-
solar_term: solar_term, solar_term_index: key)
|
151
|
-
end
|
92
|
+
solar_term_index
|
152
93
|
end
|
153
|
-
private_class_method :apply_solar_terms_before_and_after
|
154
94
|
|
155
95
|
# :reek:TooManyStatements { max_statements: 7 }
|
156
96
|
|
157
97
|
#
|
158
|
-
#
|
98
|
+
# 月内(当月朔日から当月末日(来月朔日の前日)の間)に二十四節気があるか
|
159
99
|
# @note 大余60で一巡するため 以下2パターンがある
|
160
|
-
# *
|
161
|
-
# *
|
100
|
+
# * current_month <= next_month : (二十四節気) >= current_month && (二十四節気) < next_month
|
101
|
+
# * current_month > next_month : (二十四節気) >= current_month || (二十四節気) < next_month
|
162
102
|
#
|
163
|
-
# @param [Remainder]
|
164
|
-
# @param [Remainder]
|
165
|
-
# @param [Remainder]
|
103
|
+
# @param [Remainder] solar_term 二十四節気
|
104
|
+
# @param [Remainder] current_month 月初
|
105
|
+
# @param [Remainder] next_month 月末
|
166
106
|
#
|
167
107
|
# @return [True] 対象の二十四節気がある
|
168
108
|
# @return [False] 対象の二十四節気がない
|
169
109
|
#
|
170
|
-
def self.
|
110
|
+
def self.in_solar_term?(solar_term:, current_month:, next_month:)
|
171
111
|
# 大余で比較する
|
172
|
-
target_time =
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
112
|
+
target_time = solar_term.day
|
113
|
+
current_month_time = current_month.day
|
114
|
+
next_month_time = next_month.day
|
115
|
+
current_month_over = (target_time >= current_month_time)
|
116
|
+
next_month_under = (target_time < next_month_time)
|
177
117
|
|
178
|
-
|
118
|
+
return current_month_over && next_month_under if current_month_time <= next_month_time
|
119
|
+
|
120
|
+
current_month_over || next_month_under
|
179
121
|
end
|
180
|
-
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# :reek:TooManyStatements { max_statements: 8 }
|
181
126
|
|
182
127
|
#
|
183
128
|
# 二十四節気を設定する
|
184
129
|
#
|
185
|
-
# @param [Month]
|
186
|
-
# @param [
|
187
|
-
#
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
130
|
+
# @param [Month] current_month 当月
|
131
|
+
# @param [Month] next_month 次月
|
132
|
+
#
|
133
|
+
def set_solar_term(current_month:, next_month:)
|
134
|
+
# 安全策として無限ループは回避する
|
135
|
+
# * 最大試行回数:4回(設定なし => 設定あり => 設定あり => 設定なし)
|
136
|
+
# * 閏月は1回しか設定しない
|
137
|
+
# * 最大2回設定する(中気・節気)
|
138
|
+
(0..3).each do |_index|
|
139
|
+
in_range = SolarAverage.in_solar_term?(
|
140
|
+
solar_term: @solar_term.remainder, current_month: current_month.remainder,
|
141
|
+
next_month: next_month.remainder
|
142
|
+
)
|
143
|
+
|
144
|
+
# 範囲外
|
145
|
+
unless in_range
|
146
|
+
# 1つ以上設定されていれば切り上げる(一つ飛ばしで二十四節気を設定することはない)
|
147
|
+
break unless current_month.empty_solar_term?
|
148
|
+
|
149
|
+
next_solar_term
|
150
|
+
next
|
151
|
+
end
|
152
|
+
|
153
|
+
current_month.add_term(term: @solar_term.clone)
|
154
|
+
next_solar_term
|
155
|
+
|
156
|
+
# 宣明暦は最大2つまで
|
157
|
+
break if current_month.solar_term_size == 2
|
197
158
|
end
|
159
|
+
end
|
198
160
|
|
199
|
-
|
161
|
+
#
|
162
|
+
# 次の二十四節気に移る
|
163
|
+
#
|
164
|
+
def next_solar_term
|
165
|
+
@solar_term.next!
|
200
166
|
end
|
201
|
-
private_class_method :set_solar_term
|
202
167
|
end
|
203
168
|
end
|
204
169
|
end
|