zakuro 0.0.1 → 0.1.2
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/.editorconfig +4 -0
- data/.gitignore +7 -1
- data/.rubocop.yml +3 -0
- data/Gemfile +2 -0
- data/Makefile +2 -0
- data/README.md +126 -33
- data/Rakefile +1 -1
- data/doc/gengou.md +315 -0
- 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/condition.rb +19 -15
- data/lib/zakuro/cycle/abstract_remainder.rb +3 -4
- 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/japan/yaml/set-001-until-south.yaml +1121 -0
- data/lib/zakuro/era/japan/yaml/set-002-from-north.yaml +485 -0
- data/lib/zakuro/era/japan/yaml/set-003-modern.yaml +28 -0
- data/lib/zakuro/era/western.rb +11 -1
- 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 +2 -0
- data/lib/zakuro/output/logger.rb +2 -0
- data/lib/zakuro/output/response.rb +21 -19
- 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/senmyou/README.md +3 -1
- data/lib/zakuro/version/senmyou/base/era.rb +3 -1
- data/lib/zakuro/version/senmyou/base/multi_gengou.rb +98 -0
- data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +217 -0
- data/lib/zakuro/version/senmyou/base/remainder.rb +4 -4
- data/lib/zakuro/version/senmyou/base/solar_term.rb +82 -0
- data/lib/zakuro/version/senmyou/base/year.rb +52 -6
- data/lib/zakuro/version/senmyou/monthly/first_day.rb +44 -0
- data/lib/zakuro/version/senmyou/monthly/initialized_month.rb +119 -0
- data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +3 -3
- data/lib/zakuro/version/senmyou/monthly/month.rb +136 -67
- data/lib/zakuro/version/senmyou/monthly/month_label.rb +87 -0
- data/lib/zakuro/version/senmyou/monthly/operated_month.rb +196 -0
- data/lib/zakuro/version/senmyou/{summary/annual_data.rb → range/annual_range.rb} +34 -61
- data/lib/zakuro/version/senmyou/range/full_range.rb +194 -0
- data/lib/zakuro/version/senmyou/range/operated_range.rb +126 -0
- data/lib/zakuro/version/senmyou/range/operated_solar_terms.rb +181 -0
- data/lib/zakuro/version/senmyou/range/western_date_allocation.rb +68 -0
- data/lib/zakuro/version/senmyou/range/year_boundary.rb +138 -0
- data/lib/zakuro/version/senmyou/senmyou.rb +2 -2
- data/lib/zakuro/version/senmyou/specifier/single_day_specifier.rb +102 -0
- data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +2 -2
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +105 -128
- data/lib/zakuro/version/senmyou/stella/solar_location.rb +213 -0
- data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +4 -189
- data/lib/zakuro/version/senmyou/summary/single.rb +125 -0
- data/lib/zakuro/version_factory.rb +1 -1
- metadata +46 -15
- data/lib/zakuro/era/gengou/set-001-until-south.yaml +0 -375
- data/lib/zakuro/era/gengou/set-002-from-north.yaml +0 -166
- data/lib/zakuro/era/gengou/set-003-modern.yaml +0 -12
- data/lib/zakuro/era/japan.rb +0 -630
- data/lib/zakuro/output/result.rb +0 -219
- data/lib/zakuro/version/senmyou/base/gengou.rb +0 -210
- data/lib/zakuro/version/senmyou/summary/gengou_data.rb +0 -294
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# TODO: moduleでMonthly とする(全暦むけに共通化したあと)
|
4
|
+
|
5
|
+
# :nodoc:
|
6
|
+
module Zakuro
|
7
|
+
# :nodoc:
|
8
|
+
module Senmyou
|
9
|
+
#
|
10
|
+
# MonthLabel 月表示情報
|
11
|
+
#
|
12
|
+
class MonthLabel
|
13
|
+
# @return [True] 大の月(30日)
|
14
|
+
# @return [False] 小の月(29日)
|
15
|
+
attr_reader :is_many_days
|
16
|
+
# @return [Integer] 月(xx月のxx)
|
17
|
+
attr_reader :number
|
18
|
+
# @return [True] 閏月
|
19
|
+
# @return [False] 平月
|
20
|
+
attr_reader :leaped
|
21
|
+
|
22
|
+
# :reek:ControlParameter and :reek:BooleanParameter
|
23
|
+
|
24
|
+
#
|
25
|
+
# 初期化
|
26
|
+
#
|
27
|
+
# @param [Integer] number 月(xx月のxx)
|
28
|
+
# @param [True, False] is_many_days 月の大小
|
29
|
+
# @param [True, False] leaped 閏月/平月
|
30
|
+
#
|
31
|
+
def initialize(number: -1, is_many_days: false, leaped: false)
|
32
|
+
# 月の大小
|
33
|
+
@is_many_days = is_many_days
|
34
|
+
# 月
|
35
|
+
@number = number
|
36
|
+
# 閏
|
37
|
+
@leaped = leaped
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# 月の日数を返す
|
42
|
+
#
|
43
|
+
# @return [Integer] 日数
|
44
|
+
#
|
45
|
+
def days
|
46
|
+
@is_many_days ? 30 : 29
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# 月の名前(大小)を返す
|
51
|
+
#
|
52
|
+
# @return [String] 月の名前(大小)
|
53
|
+
#
|
54
|
+
def days_name
|
55
|
+
@is_many_days ? '大' : '小'
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# 一ヶ月戻す
|
60
|
+
#
|
61
|
+
# @return [True] 昨年
|
62
|
+
# @return [False] 今年
|
63
|
+
#
|
64
|
+
def back_to_last_month
|
65
|
+
@number -= 1
|
66
|
+
|
67
|
+
return false if @number.positive?
|
68
|
+
|
69
|
+
@number = 12
|
70
|
+
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# 同一の月情報かを検証する
|
76
|
+
#
|
77
|
+
# @param [Month] other 他の月情報
|
78
|
+
#
|
79
|
+
# @return [True] 同一の月
|
80
|
+
# @return [False] 異なる月
|
81
|
+
#
|
82
|
+
def same?(other:)
|
83
|
+
@number == other.number && @leaped == other.leaped
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './month'
|
4
|
+
require_relative '../../../operation/operation'
|
5
|
+
|
6
|
+
# :nodoc:
|
7
|
+
module Zakuro
|
8
|
+
# :nodoc:
|
9
|
+
module Senmyou
|
10
|
+
# :reek:TooManyInstanceVariables { max_instance_variables: 5 }
|
11
|
+
|
12
|
+
#
|
13
|
+
# OperatedMonth 月情報(運用)
|
14
|
+
#
|
15
|
+
class OperatedMonth < Month
|
16
|
+
# @return [Operation::MonthHistory] 変更履歴(月)
|
17
|
+
attr_reader :history
|
18
|
+
# @return [OperatedSolarTerms] 運用時二十四節気
|
19
|
+
attr_reader :operated_solar_terms
|
20
|
+
|
21
|
+
#
|
22
|
+
# 初期化
|
23
|
+
#
|
24
|
+
# @param [OperatedSolarTerms] operated_solar_terms 運用時二十四節気
|
25
|
+
# @param [MonthLabel] month_label 月表示名
|
26
|
+
# @param [FirstDay] first_day 月初日(朔日)
|
27
|
+
# @param [Array<SolarTerm>] solar_terms 二十四節気
|
28
|
+
# @param [Operation::MonthHistory] history 変更履歴(月)
|
29
|
+
#
|
30
|
+
def initialize(operated_solar_terms:, month_label: MonthLabel.new, first_day: FirstDay.new,
|
31
|
+
solar_terms: [], history: Operation::MonthHistory.new)
|
32
|
+
super(month_label: month_label, first_day: first_day, solar_terms: solar_terms)
|
33
|
+
@history = history
|
34
|
+
@operated_solar_terms = operated_solar_terms
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# 書き換える
|
39
|
+
#
|
40
|
+
def rewrite
|
41
|
+
rewrite_month
|
42
|
+
rewrite_solar_terms
|
43
|
+
rewrite_first_day
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# 月ごとの差分で書き換える
|
48
|
+
#
|
49
|
+
def rewrite_month
|
50
|
+
diff = history.diffs.month
|
51
|
+
|
52
|
+
@month_label = MonthLabel.new(
|
53
|
+
number: OperatedMonth.rewrite_month_fields(
|
54
|
+
month_diff: diff, month_label: month_label, name: 'number'
|
55
|
+
),
|
56
|
+
is_many_days: OperatedMonth.rewrite_month_fields(
|
57
|
+
month_diff: diff, month_label: month_label, name: 'is_many_days'
|
58
|
+
),
|
59
|
+
leaped: OperatedMonth.rewrite_month_fields(
|
60
|
+
month_diff: diff, month_label: month_label, name: 'leaped'
|
61
|
+
)
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.rewrite_month_fields(month_diff:, month_label:, name:)
|
66
|
+
method_name = name.intern
|
67
|
+
|
68
|
+
diff = month_diff.send(method_name)
|
69
|
+
default = month_label.send(method_name)
|
70
|
+
return default if diff.invalid?
|
71
|
+
|
72
|
+
diff.actual
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# 二十四節気ごとの差分で書き換える
|
77
|
+
#
|
78
|
+
def rewrite_solar_terms
|
79
|
+
matched, operated_solar_term = @operated_solar_terms.get(
|
80
|
+
western_date: first_day.western_date
|
81
|
+
)
|
82
|
+
|
83
|
+
return unless matched
|
84
|
+
|
85
|
+
@solar_terms = OperatedMonth.create_operated_solar_terms(
|
86
|
+
operated_solar_term: operated_solar_term,
|
87
|
+
solar_terms: solar_terms
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# <Description>
|
93
|
+
#
|
94
|
+
# @param [<Type>] operated_solar_term <description>
|
95
|
+
# @param [Array<SolarTerm>] solar_terms 二十四節気
|
96
|
+
#
|
97
|
+
# @return [Array<SolarTerm>] 二十四節気
|
98
|
+
#
|
99
|
+
def self.create_operated_solar_terms(operated_solar_term:, solar_terms:)
|
100
|
+
index = operated_solar_term.index
|
101
|
+
|
102
|
+
# 別の月に移動する二十四節気。割り当てない。
|
103
|
+
result = remove_solar_term(index: index, solar_terms: solar_terms)
|
104
|
+
|
105
|
+
return result if used_solar_term?(index: index, solar_terms: solar_terms)
|
106
|
+
|
107
|
+
result.push(operated_solar_term)
|
108
|
+
|
109
|
+
result
|
110
|
+
end
|
111
|
+
|
112
|
+
# :reek:ControlParameter
|
113
|
+
|
114
|
+
#
|
115
|
+
# 二十四節気が使用されているか
|
116
|
+
#
|
117
|
+
# @param [Integer] index 二十四節気番号
|
118
|
+
# @param [Array<SolarTerm>] solar_terms 二十四節気
|
119
|
+
#
|
120
|
+
# @return [True] 使用
|
121
|
+
# @return [False] 未使用
|
122
|
+
#
|
123
|
+
def self.used_solar_term?(index:, solar_terms:)
|
124
|
+
solar_terms.each do |solar_term|
|
125
|
+
return true if index == solar_term.index
|
126
|
+
end
|
127
|
+
|
128
|
+
false
|
129
|
+
end
|
130
|
+
|
131
|
+
# :reek:ControlParameter
|
132
|
+
|
133
|
+
#
|
134
|
+
# 対象の二十四節気を除外する
|
135
|
+
#
|
136
|
+
# @param [Integer] index 二十四節気番号
|
137
|
+
# @param [Array<SolarTerm>] solar_terms 二十四節気
|
138
|
+
#
|
139
|
+
# @return [Array<SolarTerm>] 二十四節気(対象除外済)
|
140
|
+
#
|
141
|
+
def self.remove_solar_term(index:, solar_terms:)
|
142
|
+
result = []
|
143
|
+
solar_terms.each do |solar_term|
|
144
|
+
next if index == solar_term.index
|
145
|
+
|
146
|
+
result.push(solar_term)
|
147
|
+
end
|
148
|
+
|
149
|
+
result
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# 月初日ごとの差分で書き換える
|
154
|
+
#
|
155
|
+
def rewrite_first_day
|
156
|
+
diffs = @history.diffs
|
157
|
+
return if diffs.invalid_days?
|
158
|
+
|
159
|
+
days = diffs.days
|
160
|
+
|
161
|
+
@first_day = FirstDay.new(
|
162
|
+
western_date: rewrite_western_date(days: days),
|
163
|
+
remainder: rewrite_remainder(days: days)
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# 月初日の大余小余を日差分で書き換える
|
169
|
+
#
|
170
|
+
# @param [Integer] days 日差分
|
171
|
+
#
|
172
|
+
# @return [Remainder] 月初日の大余小余
|
173
|
+
#
|
174
|
+
def rewrite_remainder(days:)
|
175
|
+
remainder = first_day.remainder.clone
|
176
|
+
remainder.add!(Remainder.new(day: days, minute: 0, second: 0))
|
177
|
+
|
178
|
+
remainder
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
# 月初日の西暦日を日差分で書き換える
|
183
|
+
#
|
184
|
+
# @param [Integer] days 日差分
|
185
|
+
#
|
186
|
+
# @return [Western::Calendar] 月初日の西暦日
|
187
|
+
#
|
188
|
+
def rewrite_western_date(days:)
|
189
|
+
western_date = first_day.western_date.clone
|
190
|
+
western_date += days
|
191
|
+
|
192
|
+
western_date
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -2,21 +2,24 @@
|
|
2
2
|
|
3
3
|
require_relative '../../../output/logger'
|
4
4
|
require_relative '../base/remainder'
|
5
|
-
require_relative '../monthly/
|
5
|
+
require_relative '../monthly/initialized_month'
|
6
6
|
require_relative '../base/solar_term'
|
7
7
|
require_relative '../monthly/lunar_phase'
|
8
8
|
require_relative '../stella/solar_orbit'
|
9
9
|
require_relative '../stella/solar_average'
|
10
|
+
require_relative '../stella/solar_location'
|
10
11
|
require_relative '../stella/lunar_orbit'
|
11
12
|
|
12
13
|
# :nodoc:
|
13
14
|
module Zakuro
|
14
15
|
# :nodoc:
|
15
16
|
module Senmyou
|
16
|
-
#
|
17
|
-
|
17
|
+
#
|
18
|
+
# AnnualRange 年間範囲
|
19
|
+
#
|
20
|
+
module AnnualRange
|
18
21
|
# @return [Logger] ロガー
|
19
|
-
LOGGER = Logger.new(location: '
|
22
|
+
LOGGER = Logger.new(location: 'annual_range')
|
20
23
|
|
21
24
|
# :reek:TooManyStatements { max_statements: 6 }
|
22
25
|
|
@@ -61,20 +64,18 @@ module Zakuro
|
|
61
64
|
#
|
62
65
|
# @return [Array<Month>] 1年データ
|
63
66
|
#
|
64
|
-
def self.
|
65
|
-
|
67
|
+
def self.collect_annual_range_after_last_november_1st(western_year:)
|
68
|
+
annual_range = initialized_annual_range(western_year: western_year)
|
66
69
|
|
67
|
-
apply_big_and_small_of_the_month(
|
70
|
+
apply_big_and_small_of_the_month(annual_range: annual_range)
|
68
71
|
|
69
|
-
SolarAverage.
|
70
|
-
|
72
|
+
solar_average = SolarAverage.new(western_year: western_year)
|
73
|
+
solar_average.set(annual_range: annual_range)
|
71
74
|
|
72
75
|
# 月間隔を取得するためだけの末尾要素を削除
|
73
|
-
|
76
|
+
annual_range.pop
|
74
77
|
|
75
|
-
|
76
|
-
|
77
|
-
annual_data
|
78
|
+
initialize_month_label(annual_range: annual_range)
|
78
79
|
end
|
79
80
|
|
80
81
|
#
|
@@ -91,7 +92,7 @@ module Zakuro
|
|
91
92
|
remainder: winter_solstice_age
|
92
93
|
)
|
93
94
|
solar_term = \
|
94
|
-
|
95
|
+
SolarLocation.get(
|
95
96
|
solar_term: solar_term
|
96
97
|
)
|
97
98
|
|
@@ -112,75 +113,47 @@ module Zakuro
|
|
112
113
|
#
|
113
114
|
# @return [Array<Month>] 1年データ
|
114
115
|
#
|
115
|
-
def self.
|
116
|
+
def self.initialized_annual_range(western_year:)
|
116
117
|
result = []
|
117
118
|
lunar_phase = LunarPhase.new(western_year: western_year)
|
118
119
|
|
119
|
-
|
120
|
-
|
121
|
-
monthes = [11, 12] + [*1..12]
|
122
|
-
|
123
|
-
monthes.each do |month|
|
124
|
-
LOGGER.debug('---', "month: #{month}", "is_last_year: #{is_last_year}")
|
125
|
-
|
120
|
+
# 14ヶ月分を生成する(閏年で最大13ヶ月 + 末月の大小/二十四節気を求めるために必要な月)
|
121
|
+
(0..13).each do |_index|
|
126
122
|
adjusted = lunar_phase.next_month
|
127
123
|
|
128
124
|
result.push(
|
129
|
-
|
130
|
-
|
125
|
+
InitializedMonth.new(month_label: MonthLabel.new,
|
126
|
+
first_day: FirstDay.new(remainder: adjusted),
|
127
|
+
phase_index: 0)
|
131
128
|
)
|
132
|
-
is_last_year = false if month == 12
|
133
129
|
end
|
130
|
+
|
134
131
|
result
|
135
132
|
end
|
136
|
-
private_class_method :
|
133
|
+
private_class_method :initialized_annual_range
|
137
134
|
|
138
135
|
#
|
139
136
|
# 1年データの各月に月の大小を設定する
|
140
137
|
#
|
141
|
-
# @param [Array<Month>]
|
142
|
-
#
|
143
|
-
def self.apply_big_and_small_of_the_month(
|
144
|
-
|
145
|
-
(
|
146
|
-
current_month
|
147
|
-
next_month = annual_data[idx + 1]
|
148
|
-
current_month.is_many_days = \
|
149
|
-
current_month.remainder.same_remainder_divided_by_ten?(
|
150
|
-
other: next_month.remainder.day
|
151
|
-
)
|
138
|
+
# @param [Array<Month>] annual_range 1年データ
|
139
|
+
#
|
140
|
+
def self.apply_big_and_small_of_the_month(annual_range:)
|
141
|
+
# NOTE: 最後の月は処理できない(=計算外の余分な月が最後に必要である)
|
142
|
+
annual_range.each_cons(2) do |(current_month, next_month)|
|
143
|
+
current_month.eval_many_days(next_month_day: next_month.remainder.day)
|
152
144
|
end
|
153
145
|
end
|
154
146
|
private_class_method :apply_big_and_small_of_the_month
|
155
147
|
|
156
|
-
# :reek:TooManyStatements { max_statements: 10 }
|
157
|
-
|
158
148
|
#
|
159
|
-
#
|
160
|
-
# @example 7,8,9 と続く月の8月が閏の場合、7, 閏7, 8 となる
|
149
|
+
# 月表示情報を更新する
|
161
150
|
#
|
162
|
-
# @param [Array<Month>]
|
151
|
+
# @param [Array<Month>] annual_range 1年データ
|
163
152
|
#
|
164
|
-
def self.
|
165
|
-
|
166
|
-
leaped = false
|
167
|
-
annual_data.each do |month|
|
168
|
-
if month.even_term.invalid?
|
169
|
-
month.leaped = true
|
170
|
-
leaped = true
|
171
|
-
end
|
172
|
-
next unless leaped
|
173
|
-
|
174
|
-
# NOTE: 常気法では閏月は2-3年に一度のため、1年に二度発生しない前提
|
175
|
-
number = month.number - 1
|
176
|
-
if number <= 0
|
177
|
-
month.is_last_year = true
|
178
|
-
number = 12
|
179
|
-
end
|
180
|
-
month.number = number
|
181
|
-
end
|
153
|
+
def self.initialize_month_label(annual_range:)
|
154
|
+
annual_range.each(&:rename_month_label_by_solar_term)
|
182
155
|
end
|
183
|
-
private_class_method :
|
156
|
+
private_class_method :initialize_month_label
|
184
157
|
end
|
185
158
|
end
|
186
159
|
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../base/multi_gengou_roller'
|
4
|
+
|
5
|
+
require_relative '../../../era/western'
|
6
|
+
require_relative './annual_range'
|
7
|
+
require_relative './year_boundary'
|
8
|
+
require_relative './western_date_allocation'
|
9
|
+
|
10
|
+
require_relative '../base/year'
|
11
|
+
|
12
|
+
# :nodoc:
|
13
|
+
module Zakuro
|
14
|
+
# :nodoc:
|
15
|
+
module Senmyou
|
16
|
+
# :reek:TooManyInstanceVariables { max_instance_variables: 5 }
|
17
|
+
|
18
|
+
#
|
19
|
+
# FullRange 完全範囲
|
20
|
+
# ある日からある日の範囲を計算可能な年月範囲
|
21
|
+
# * 前提として元号年はその元号の開始年から数える
|
22
|
+
# * ある日の元号年を求める場合、その元号が含まれる最初の年まで遡る
|
23
|
+
# * 元号は一つとは限らない。南北朝などで二つある場合は、古い方の元号から求める
|
24
|
+
#
|
25
|
+
# NOTE: 割り当てた元号は年初を基準にした元号年である
|
26
|
+
# * 元旦を基準にした時の正しい元号を設定している
|
27
|
+
# * 引き当てたい日付が元旦ではない場合、その月日に従い元号を再度求める
|
28
|
+
# * この再計算が必要になるのは、元号が切り替わる年のみである
|
29
|
+
#
|
30
|
+
class FullRange
|
31
|
+
# @return [Western::Calendar] 開始日
|
32
|
+
attr_reader :start_date
|
33
|
+
# @return [Western::Calendar] 終了日
|
34
|
+
attr_reader :end_date
|
35
|
+
# @return [MultiGengouRoller] 改元処理
|
36
|
+
attr_reader :multi_gengou_roller
|
37
|
+
# @return [Western::Calendar] 最過去の元旦
|
38
|
+
attr_reader :new_year_date
|
39
|
+
# @return [Integer] 西暦年
|
40
|
+
attr_reader :western_year
|
41
|
+
|
42
|
+
# @return [Logger] ロガー
|
43
|
+
LOGGER = Logger.new(location: 'full_range')
|
44
|
+
|
45
|
+
#
|
46
|
+
# 初期化
|
47
|
+
#
|
48
|
+
# @param [Western::Calendar] start_date 開始日
|
49
|
+
# @param [Western::Calendar] end_date 終了日
|
50
|
+
#
|
51
|
+
def initialize(start_date: Western::Calendar.new, end_date: Western::Calendar.new)
|
52
|
+
@start_date = start_date
|
53
|
+
@end_date = end_date
|
54
|
+
return if invalid?
|
55
|
+
|
56
|
+
@multi_gengou_roller = MultiGengouRoller.new(start_date: start_date, end_date: end_date)
|
57
|
+
@new_year_date = @multi_gengou_roller.oldest_date.clone
|
58
|
+
@western_year = @new_year_date.year
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# 無効か
|
63
|
+
#
|
64
|
+
# @return [True] 無効
|
65
|
+
# @return [False] 有効
|
66
|
+
#
|
67
|
+
def invalid?
|
68
|
+
@start_date.invalid?
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# 完全範囲を取得する
|
73
|
+
#
|
74
|
+
# @return [Array<Year>] 完全範囲
|
75
|
+
#
|
76
|
+
def get
|
77
|
+
return [] if invalid?
|
78
|
+
|
79
|
+
years = YearBoundary.get(annual_ranges: annual_ranges)
|
80
|
+
years = update_gengou(years: years)
|
81
|
+
|
82
|
+
WesternDateAllocation.update_first_day(years: years)
|
83
|
+
|
84
|
+
years
|
85
|
+
end
|
86
|
+
|
87
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
88
|
+
|
89
|
+
#
|
90
|
+
# 完全範囲内の年データを取得する
|
91
|
+
#
|
92
|
+
# @return [Array<Year>] 年データ(冬至基準)
|
93
|
+
#
|
94
|
+
def annual_ranges
|
95
|
+
oldest_date = @new_year_date
|
96
|
+
newest_date = @multi_gengou_roller.newest_date
|
97
|
+
|
98
|
+
years = []
|
99
|
+
((oldest_date.year)..(newest_date.year + 2)).each do |year|
|
100
|
+
years.push(
|
101
|
+
AnnualRange.collect_annual_range_after_last_november_1st(
|
102
|
+
western_year: year
|
103
|
+
)
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
107
|
+
years
|
108
|
+
end
|
109
|
+
|
110
|
+
# :reek:TooManyStatements { max_statements: 8 }
|
111
|
+
|
112
|
+
#
|
113
|
+
# 完全範囲内の年データの元号を開始年基準で更新する
|
114
|
+
#
|
115
|
+
# @param [Array<Year>] years 年データ(元旦基準)
|
116
|
+
#
|
117
|
+
# @return [Array<Year>] 元号更新済み年データ(元旦基準)
|
118
|
+
#
|
119
|
+
def update_gengou(years:)
|
120
|
+
updated_years = []
|
121
|
+
|
122
|
+
nearest_end_date = choise_nearest_end_date
|
123
|
+
|
124
|
+
years.each do |year|
|
125
|
+
next_year(years: updated_years, year: year)
|
126
|
+
|
127
|
+
if @new_year_date > nearest_end_date
|
128
|
+
@multi_gengou_roller.transfer
|
129
|
+
nearest_end_date = choise_nearest_end_date
|
130
|
+
end
|
131
|
+
@multi_gengou_roller.next_year
|
132
|
+
end
|
133
|
+
|
134
|
+
updated_years
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
#
|
140
|
+
# 元号処理対象の年を進める
|
141
|
+
#
|
142
|
+
# @param [Array<Year>] years 元号処理済み年データ(元旦基準)
|
143
|
+
# @param [Year] year 元号処理前の年(元旦基準)
|
144
|
+
#
|
145
|
+
def next_year(years:, year:)
|
146
|
+
updated_year = update_year(year: year)
|
147
|
+
|
148
|
+
years.push(updated_year)
|
149
|
+
|
150
|
+
next_new_year_date(total_days: updated_year.total_days)
|
151
|
+
|
152
|
+
nil
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# 年の元号を更新する
|
157
|
+
#
|
158
|
+
# @param [Year] year 元号処理前の年(元旦基準)
|
159
|
+
#
|
160
|
+
# @return [Year] 元号処理済の年(元旦基準)
|
161
|
+
#
|
162
|
+
def update_year(year:)
|
163
|
+
multi_gengou = @multi_gengou_roller.multi_gengou.clone
|
164
|
+
|
165
|
+
updated_year = Year.new(multi_gengou: multi_gengou, new_year_date: @new_year_date.clone,
|
166
|
+
months: year.months)
|
167
|
+
updated_year.commit
|
168
|
+
|
169
|
+
updated_year
|
170
|
+
end
|
171
|
+
|
172
|
+
#
|
173
|
+
# 次の年に進める
|
174
|
+
#
|
175
|
+
# @param [Integer] total_days 年の日数
|
176
|
+
#
|
177
|
+
def next_new_year_date(total_days:)
|
178
|
+
@new_year_date += total_days
|
179
|
+
@multi_gengou_roller.next(days: total_days)
|
180
|
+
|
181
|
+
nil
|
182
|
+
end
|
183
|
+
|
184
|
+
#
|
185
|
+
# 現在日からみて直近の未来に対する元号の切替前日を求める
|
186
|
+
#
|
187
|
+
# @return [Western::Calendar] 元号の切替前日
|
188
|
+
#
|
189
|
+
def choise_nearest_end_date
|
190
|
+
@multi_gengou_roller.choise_nearest_end_date
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|