zakuro 0.0.3 → 0.1.4
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/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 +173 -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 +125 -0
- data/lib/zakuro/calculation/monthly/month.rb +187 -0
- data/lib/zakuro/calculation/monthly/month_label.rb +88 -0
- data/lib/zakuro/calculation/monthly/operated_month.rb +209 -0
- data/lib/zakuro/calculation/range/full_range.rb +210 -0
- data/lib/zakuro/calculation/range/operated_range.rb +144 -0
- data/lib/zakuro/calculation/range/operated_solar_terms.rb +201 -0
- data/lib/zakuro/calculation/range/transfer/western_date_allocation.rb +82 -0
- data/lib/zakuro/calculation/range/transfer/year_boundary.rb +146 -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 +16 -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 +0 -0
- 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 +167 -0
- data/lib/zakuro/version/senmyou/senmyou.rb +10 -4
- data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +6 -6
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +103 -152
- data/lib/zakuro/version/senmyou/stella/solar_location.rb +213 -0
- data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +3 -184
- 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 +53 -24
- data/lib/zakuro/cycle/abstract_remainder.rb +0 -456
- data/lib/zakuro/cycle/zodiac.rb +0 -103
- data/lib/zakuro/era/japan.rb +0 -664
- data/lib/zakuro/output/result.rb +0 -225
- 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 -187
- data/lib/zakuro/version/senmyou/summary/full_range.rb +0 -224
- data/lib/zakuro/version/senmyou/summary/specifier.rb +0 -100
@@ -0,0 +1,167 @@
|
|
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 [Context] context 暦コンテキスト
|
66
|
+
# @param [Integer] western_year 西暦年
|
67
|
+
#
|
68
|
+
# @return [Array<Month>] 1年データ
|
69
|
+
#
|
70
|
+
def self.collect_annual_range_after_last_november_1st(context:, western_year:)
|
71
|
+
annual_range = initialized_annual_range(context: context, western_year: western_year)
|
72
|
+
|
73
|
+
apply_big_and_small_of_the_month(annual_range: annual_range)
|
74
|
+
|
75
|
+
solar_average = SolarAverage.new(western_year: western_year)
|
76
|
+
solar_average.set(annual_range: annual_range)
|
77
|
+
|
78
|
+
# 月間隔を取得するためだけの末尾要素を削除
|
79
|
+
annual_range.pop
|
80
|
+
|
81
|
+
initialize_month_label(annual_range: annual_range)
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# 11月定朔の補正値を求める
|
86
|
+
#
|
87
|
+
# @param [Remainder] winter_solstice_age 天正閏余
|
88
|
+
# @param [Integer] western_year 西暦年
|
89
|
+
#
|
90
|
+
# @return [Integer] 補正値
|
91
|
+
#
|
92
|
+
def self.correction_value_on_last_november_1st(winter_solstice_age:, western_year:)
|
93
|
+
# 補正
|
94
|
+
solar_term = Cycle::SolarTerm.new(
|
95
|
+
remainder: winter_solstice_age
|
96
|
+
)
|
97
|
+
solar_term = \
|
98
|
+
SolarLocation.get(
|
99
|
+
solar_term: solar_term
|
100
|
+
)
|
101
|
+
|
102
|
+
moon_remainder, is_forward = LunarOrbit.calc_moon_point(
|
103
|
+
remainder: winter_solstice_age, western_year: western_year
|
104
|
+
)
|
105
|
+
|
106
|
+
SolarOrbit.calc_sun_orbit_value(solar_term: solar_term) +
|
107
|
+
LunarOrbit.calc_moon_orbit_value(remainder_month: moon_remainder,
|
108
|
+
is_forward: is_forward)
|
109
|
+
end
|
110
|
+
private_class_method :correction_value_on_last_november_1st
|
111
|
+
|
112
|
+
#
|
113
|
+
# 1年データを取得する
|
114
|
+
#
|
115
|
+
# @param [Context] context 暦コンテキスト
|
116
|
+
# @param [Integer] western_year 西暦年
|
117
|
+
#
|
118
|
+
# @return [Array<Month>] 1年データ
|
119
|
+
#
|
120
|
+
def self.initialized_annual_range(context:, western_year:)
|
121
|
+
result = []
|
122
|
+
lunar_phase = Monthly::LunarPhase.new(western_year: western_year)
|
123
|
+
|
124
|
+
# 14ヶ月分を生成する(閏年で最大13ヶ月 + 末月の大小/二十四節気を求めるために必要な月)
|
125
|
+
(0..13).each do |_index|
|
126
|
+
adjusted = lunar_phase.next_month
|
127
|
+
|
128
|
+
result.push(
|
129
|
+
Calculation::Monthly::InitializedMonth.new(
|
130
|
+
context: context,
|
131
|
+
month_label: Calculation::Monthly::MonthLabel.new,
|
132
|
+
first_day: Calculation::Monthly::FirstDay.new(remainder: adjusted),
|
133
|
+
phase_index: 0
|
134
|
+
)
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
result
|
139
|
+
end
|
140
|
+
private_class_method :initialized_annual_range
|
141
|
+
|
142
|
+
#
|
143
|
+
# 1年データの各月に月の大小を設定する
|
144
|
+
#
|
145
|
+
# @param [Array<Month>] annual_range 1年データ
|
146
|
+
#
|
147
|
+
def self.apply_big_and_small_of_the_month(annual_range:)
|
148
|
+
# NOTE: 最後の月は処理できない(=計算外の余分な月が最後に必要である)
|
149
|
+
annual_range.each_cons(2) do |(current_month, next_month)|
|
150
|
+
current_month.eval_many_days(next_month_day: next_month.remainder.day)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
private_class_method :apply_big_and_small_of_the_month
|
154
|
+
|
155
|
+
#
|
156
|
+
# 月表示情報を更新する
|
157
|
+
#
|
158
|
+
# @param [Array<Month>] annual_range 1年データ
|
159
|
+
#
|
160
|
+
def self.initialize_month_label(annual_range:)
|
161
|
+
annual_range.each(&:rename_month_label_by_solar_term)
|
162
|
+
end
|
163
|
+
private_class_method :initialize_month_label
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
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
|
@@ -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,212 +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
|
-
while month_index < month_size && solar_term_index < solar_terms.size
|
81
|
-
raise StandardError, "month is over. idx: #{month_index}" if month_index >= month_size
|
82
|
-
|
83
|
-
if set_solar_term_on_current_month(current_month: annual_range[month_index],
|
84
|
-
next_month: annual_range[month_index + 1],
|
85
|
-
solar_term: solar_terms[solar_term_index],
|
86
|
-
solar_term_index: solar_term_index)
|
87
|
-
solar_term_index += 1
|
88
|
-
next
|
89
|
-
end
|
48
|
+
# @return [SolarTerm] 二十四節気
|
49
|
+
#
|
50
|
+
def self.first_solar_term(western_year:)
|
51
|
+
# 天正冬至
|
52
|
+
winter_solstice = WinterSolstice.calc(western_year: western_year)
|
90
53
|
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
private_class_method :apply_solar_terms_from_last_winter_solstice
|
54
|
+
# 二十四節気(冬至)
|
55
|
+
solar_term = Cycle::SolarTerm.new(index: 0, remainder: winter_solstice)
|
95
56
|
|
96
|
-
|
97
|
-
# 当月に二十四節気を設定する
|
98
|
-
#
|
99
|
-
# @param [Remainder] current_month 当月
|
100
|
-
# @param [Month] next_month 次月
|
101
|
-
# @param [Month] solar_term 二十四節気
|
102
|
-
# @param [Integer] solar_term_index 二十四節気位置
|
103
|
-
#
|
104
|
-
# @return [True] 設定済
|
105
|
-
# @return [False] 未設定
|
106
|
-
#
|
107
|
-
def self.set_solar_term_on_current_month(current_month:,
|
108
|
-
next_month:, solar_term:, solar_term_index:)
|
109
|
-
if in_range_solar_term?(target: solar_term, min: current_month.remainder,
|
110
|
-
max: next_month.remainder)
|
111
|
-
set_solar_term(month: current_month,
|
112
|
-
solar_term: solar_term, solar_term_index: solar_term_index)
|
113
|
-
return true
|
114
|
-
end
|
57
|
+
first_solar_term_index = SolarAverage.calc_fist_solar_term_index(western_year: western_year)
|
115
58
|
|
116
|
-
#
|
117
|
-
|
59
|
+
# 対象の二十四節気まで戻す
|
60
|
+
solar_term.prev_by_index(first_solar_term_index)
|
118
61
|
|
119
|
-
|
62
|
+
solar_term
|
120
63
|
end
|
121
64
|
|
122
65
|
#
|
123
|
-
#
|
66
|
+
# 計算開始する二十四節気番号を求める
|
67
|
+
#
|
68
|
+
# * 前提として入定気は冬至の手前にある
|
69
|
+
# * 例えば、定気が大雪であれば入定気は大雪の範囲内にある
|
70
|
+
# * 入定気は、定気の開始位置に重複しない限り、常に定気より後にある
|
71
|
+
# * 基本的に定気の一つ前から起算すれば、当時から求めた11月(閏10/閏11月)に二十四節気を割り当てられる
|
124
72
|
#
|
125
|
-
# @param [
|
73
|
+
# @param [Integer] western_year 西暦年
|
126
74
|
#
|
127
|
-
# @return [
|
75
|
+
# @return [Integer] 二十四節気番号
|
128
76
|
#
|
129
|
-
def self.
|
130
|
-
|
77
|
+
def self.calc_fist_solar_term_index(western_year:)
|
78
|
+
# 天正閏余
|
79
|
+
winter_solstice_age = \
|
80
|
+
WinterSolstice.calc_moon_age(western_year: western_year)
|
131
81
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
# 当年冬至
|
137
|
-
0 => { index: -2, solar_term: touji },
|
138
|
-
# 当年小寒
|
139
|
-
1 => { index: -2, solar_term: touji.add(SOLAR_TERM_AVERAGE) }
|
140
|
-
}
|
141
|
-
end
|
142
|
-
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
|
+
)
|
143
86
|
|
144
|
-
|
87
|
+
solar_term_index = solar_location.index
|
145
88
|
|
146
|
-
|
147
|
-
|
148
|
-
#
|
149
|
-
# @param [Array<Month>] annual_range 1年データ
|
150
|
-
# @param [Hash<Integer, Hash<Symbol, Integer>>, Hash<Integer, Hash<Symbol, Remainder>>]
|
151
|
-
# rest_solar_terms 前後
|
152
|
-
#
|
153
|
-
def self.apply_solar_terms_before_and_after(annual_range:, rest_solar_terms:)
|
154
|
-
rest_solar_terms.each do |key, value|
|
155
|
-
index = value[:index]
|
156
|
-
solar_term = value[:solar_term]
|
157
|
-
data = annual_range[index]
|
158
|
-
next unless in_range_solar_term?(
|
159
|
-
target: solar_term,
|
160
|
-
min: data.remainder, max: annual_range[index + 1].remainder
|
161
|
-
)
|
89
|
+
# 入定気の一つ後の二十四節気まで戻す(ただし11月経朔が二十四節気上にある場合は戻さない)
|
90
|
+
solar_term_index += 1 unless solar_location.remainder == Cycle::Remainder.new(total: 0)
|
162
91
|
|
163
|
-
|
164
|
-
solar_term: solar_term, solar_term_index: key)
|
165
|
-
end
|
92
|
+
solar_term_index
|
166
93
|
end
|
167
|
-
private_class_method :apply_solar_terms_before_and_after
|
168
94
|
|
169
95
|
# :reek:TooManyStatements { max_statements: 7 }
|
170
96
|
|
171
97
|
#
|
172
|
-
#
|
98
|
+
# 月内(当月朔日から当月末日(来月朔日の前日)の間)に二十四節気があるか
|
173
99
|
# @note 大余60で一巡するため 以下2パターンがある
|
174
|
-
# *
|
175
|
-
# *
|
100
|
+
# * current_month <= next_month : (二十四節気) >= current_month && (二十四節気) < next_month
|
101
|
+
# * current_month > next_month : (二十四節気) >= current_month || (二十四節気) < next_month
|
176
102
|
#
|
177
|
-
# @param [Remainder]
|
178
|
-
# @param [Remainder]
|
179
|
-
# @param [Remainder]
|
103
|
+
# @param [Remainder] solar_term 二十四節気
|
104
|
+
# @param [Remainder] current_month 月初
|
105
|
+
# @param [Remainder] next_month 月末
|
180
106
|
#
|
181
107
|
# @return [True] 対象の二十四節気がある
|
182
108
|
# @return [False] 対象の二十四節気がない
|
183
109
|
#
|
184
|
-
def self.
|
110
|
+
def self.in_solar_term?(solar_term:, current_month:, next_month:)
|
185
111
|
# 大余で比較する
|
186
|
-
target_time =
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
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)
|
117
|
+
|
118
|
+
return current_month_over && next_month_under if current_month_time <= next_month_time
|
191
119
|
|
192
|
-
|
120
|
+
current_month_over || next_month_under
|
193
121
|
end
|
194
|
-
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
# :reek:TooManyStatements { max_statements: 8 }
|
195
126
|
|
196
127
|
#
|
197
128
|
# 二十四節気を設定する
|
198
129
|
#
|
199
|
-
# @param [Month]
|
200
|
-
# @param [
|
201
|
-
#
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
211
158
|
end
|
159
|
+
end
|
212
160
|
|
213
|
-
|
161
|
+
#
|
162
|
+
# 次の二十四節気に移る
|
163
|
+
#
|
164
|
+
def next_solar_term
|
165
|
+
@solar_term.next_term!
|
214
166
|
end
|
215
|
-
private_class_method :set_solar_term
|
216
167
|
end
|
217
168
|
end
|
218
169
|
end
|