zakuro 0.0.0 → 0.1.1
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 +156 -10
- 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/merchant.rb +3 -1
- data/lib/zakuro/operation/month/parser.rb +373 -0
- data/lib/zakuro/operation/month/type.rb +458 -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 +20 -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 +48 -0
- data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +1 -1
- 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 +167 -0
- data/lib/zakuro/version/senmyou/{summary/annual_data.rb → range/annual_range.rb} +38 -40
- data/lib/zakuro/version/senmyou/range/full_range.rb +324 -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/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 +1 -1
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +54 -32
- data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +3 -7
- data/lib/zakuro/version/senmyou/summary/single.rb +125 -0
- data/lib/zakuro/version_factory.rb +1 -1
- metadata +40 -13
- data/.travis.yml +0 -6
- 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,167 @@
|
|
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
|
+
#
|
11
|
+
# OperatedMonth 月情報(運用)
|
12
|
+
#
|
13
|
+
class OperatedMonth < Month
|
14
|
+
# @return [Operation::MonthHistory] 変更履歴(月)
|
15
|
+
attr_reader :history
|
16
|
+
# @return [OperatedSolarTerms] 運用時二十四節気
|
17
|
+
attr_reader :operated_solar_terms
|
18
|
+
|
19
|
+
#
|
20
|
+
# 初期化
|
21
|
+
#
|
22
|
+
# @param [MonthLabel] month_label 月表示名
|
23
|
+
# @param [FirstDay] first_day 月初日(朔日)
|
24
|
+
# @param [Array<SolarTerm>] solar_terms 二十四節気
|
25
|
+
# @param [Operation::MonthHistory] history 変更履歴(月)
|
26
|
+
#
|
27
|
+
def initialize(operated_solar_terms:, month_label: MonthLabel.new, first_day: FirstDay.new, solar_terms: [],
|
28
|
+
history: Operation::MonthHistory.new)
|
29
|
+
super(month_label: month_label, first_day: first_day, solar_terms: solar_terms)
|
30
|
+
@history = history
|
31
|
+
@operated_solar_terms = operated_solar_terms
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# 書き換える
|
36
|
+
#
|
37
|
+
def rewrite
|
38
|
+
rewrite_month
|
39
|
+
rewrite_solar_terms
|
40
|
+
rewrite_first_day
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# 月ごとの差分で書き換える
|
45
|
+
#
|
46
|
+
def rewrite_month
|
47
|
+
diff = history.diffs.month
|
48
|
+
|
49
|
+
@month_label = MonthLabel.new(
|
50
|
+
number: rewrite_number(diff: diff.number),
|
51
|
+
is_many_days: rewrite_many_days(diff: diff.days),
|
52
|
+
leaped: rewrite_leaped(diff: diff.leaped)
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# 月ごとの差分(月)で書き換える
|
58
|
+
#
|
59
|
+
# @param [Operation::Number] diff 差分
|
60
|
+
#
|
61
|
+
# @return [Integer] 月
|
62
|
+
#
|
63
|
+
def rewrite_number(diff:)
|
64
|
+
return month_label.number if diff.invalid?
|
65
|
+
|
66
|
+
diff.actual
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# 月ごとの差分(月の大小)で書き換える
|
71
|
+
#
|
72
|
+
# @param [Operation::Days] diff 差分
|
73
|
+
#
|
74
|
+
# @return [Integer] 月の大小
|
75
|
+
#
|
76
|
+
def rewrite_many_days(diff:)
|
77
|
+
return month_label.is_many_days if diff.invalid?
|
78
|
+
|
79
|
+
diff.many_days_actual?
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# 月ごとの差分(閏有無)で書き換える
|
84
|
+
#
|
85
|
+
# @param [Operation::Days] diff 差分
|
86
|
+
#
|
87
|
+
# @return [True] 閏あり
|
88
|
+
# @return [False] 閏なし
|
89
|
+
#
|
90
|
+
def rewrite_leaped(diff:)
|
91
|
+
return month_label.leaped if diff.invalid?
|
92
|
+
|
93
|
+
diff.actual
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# 二十四節気ごとの差分で書き換える
|
98
|
+
#
|
99
|
+
def rewrite_solar_terms
|
100
|
+
# TODO: リファクタリング
|
101
|
+
operated_solar_terms = []
|
102
|
+
matched, operated_solar_term = @operated_solar_terms.get(
|
103
|
+
western_date: @first_day.western_date
|
104
|
+
)
|
105
|
+
|
106
|
+
return unless matched
|
107
|
+
|
108
|
+
used = false
|
109
|
+
@solar_terms.each do |solar_term|
|
110
|
+
if operated_solar_term.index == solar_term.index
|
111
|
+
used = true
|
112
|
+
next
|
113
|
+
end
|
114
|
+
|
115
|
+
operated_solar_terms.push(solar_term)
|
116
|
+
end
|
117
|
+
|
118
|
+
operated_solar_terms.push(operated_solar_term) unless used
|
119
|
+
|
120
|
+
@solar_terms = operated_solar_terms
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# 月初日ごとの差分で書き換える
|
125
|
+
#
|
126
|
+
def rewrite_first_day
|
127
|
+
diffs = @history.diffs
|
128
|
+
return if diffs.invalid_days?
|
129
|
+
|
130
|
+
days = diffs.days
|
131
|
+
|
132
|
+
@first_day = FirstDay.new(
|
133
|
+
western_date: rewrite_western_date(days: days),
|
134
|
+
remainder: rewrite_remainder(days: days)
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# 月初日の大余小余を日差分で書き換える
|
140
|
+
#
|
141
|
+
# @param [Integer] days 日差分
|
142
|
+
#
|
143
|
+
# @return [Remainder] 月初日の大余小余
|
144
|
+
#
|
145
|
+
def rewrite_remainder(days:)
|
146
|
+
remainder = @first_day.remainder.clone
|
147
|
+
remainder.add!(Remainder.new(day: days, minute: 0, second: 0))
|
148
|
+
|
149
|
+
remainder
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# 月初日の西暦日を日差分で書き換える
|
154
|
+
#
|
155
|
+
# @param [Integer] days 日差分
|
156
|
+
#
|
157
|
+
# @return [Western::Calendar] 月初日の西暦日
|
158
|
+
#
|
159
|
+
def rewrite_western_date(days:)
|
160
|
+
western_date = @first_day.western_date.clone
|
161
|
+
western_date += days
|
162
|
+
|
163
|
+
western_date
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -2,7 +2,7 @@
|
|
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'
|
@@ -13,10 +13,12 @@ require_relative '../stella/lunar_orbit'
|
|
13
13
|
module Zakuro
|
14
14
|
# :nodoc:
|
15
15
|
module Senmyou
|
16
|
-
#
|
17
|
-
|
16
|
+
#
|
17
|
+
# AnnualRange 年間範囲
|
18
|
+
#
|
19
|
+
module AnnualRange
|
18
20
|
# @return [Logger] ロガー
|
19
|
-
LOGGER = Logger.new(location: '
|
21
|
+
LOGGER = Logger.new(location: 'annual_range')
|
20
22
|
|
21
23
|
# :reek:TooManyStatements { max_statements: 6 }
|
22
24
|
|
@@ -61,20 +63,20 @@ module Zakuro
|
|
61
63
|
#
|
62
64
|
# @return [Array<Month>] 1年データ
|
63
65
|
#
|
64
|
-
def self.
|
65
|
-
|
66
|
+
def self.collect_annual_range_after_last_november_1st(western_year:)
|
67
|
+
annual_range = initialized_annual_range(western_year: western_year)
|
66
68
|
|
67
|
-
apply_big_and_small_of_the_month(
|
69
|
+
apply_big_and_small_of_the_month(annual_range: annual_range)
|
68
70
|
|
69
|
-
SolarAverage.
|
70
|
-
|
71
|
+
SolarAverage.set_solar_terms_into_annual_range(western_year: western_year,
|
72
|
+
annual_range: annual_range)
|
71
73
|
|
72
74
|
# 月間隔を取得するためだけの末尾要素を削除
|
73
|
-
|
75
|
+
annual_range.pop
|
74
76
|
|
75
|
-
adjust_leap_month(
|
77
|
+
adjust_leap_month(annual_range: annual_range)
|
76
78
|
|
77
|
-
|
79
|
+
annual_range
|
78
80
|
end
|
79
81
|
|
80
82
|
#
|
@@ -112,7 +114,7 @@ module Zakuro
|
|
112
114
|
#
|
113
115
|
# @return [Array<Month>] 1年データ
|
114
116
|
#
|
115
|
-
def self.
|
117
|
+
def self.initialized_annual_range(western_year:)
|
116
118
|
result = []
|
117
119
|
lunar_phase = LunarPhase.new(western_year: western_year)
|
118
120
|
|
@@ -126,29 +128,28 @@ module Zakuro
|
|
126
128
|
adjusted = lunar_phase.next_month
|
127
129
|
|
128
130
|
result.push(
|
129
|
-
|
130
|
-
|
131
|
+
InitializedMonth.new(month_label: MonthLabel.new(number: month),
|
132
|
+
first_day: FirstDay.new(remainder: adjusted),
|
133
|
+
is_last_year: is_last_year, phase_index: 0)
|
131
134
|
)
|
132
135
|
is_last_year = false if month == 12
|
133
136
|
end
|
134
137
|
result
|
135
138
|
end
|
136
|
-
private_class_method :
|
139
|
+
private_class_method :initialized_annual_range
|
137
140
|
|
138
141
|
#
|
139
142
|
# 1年データの各月に月の大小を設定する
|
140
143
|
#
|
141
|
-
# @param [Array<Month>]
|
142
|
-
#
|
143
|
-
def self.apply_big_and_small_of_the_month(
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
other: next_month.remainder.day
|
151
|
-
)
|
144
|
+
# @param [Array<Month>] annual_range 1年データ
|
145
|
+
#
|
146
|
+
def self.apply_big_and_small_of_the_month(annual_range:)
|
147
|
+
annual_range.each_with_index do |range, index|
|
148
|
+
# 最後は比較対象がないためスキップする(=計算外の余分な月が最後に必要である)
|
149
|
+
next if index == annual_range.size - 1
|
150
|
+
|
151
|
+
next_month = annual_range[index + 1]
|
152
|
+
range.eval_many_days(next_month_day: next_month.remainder.day)
|
152
153
|
end
|
153
154
|
end
|
154
155
|
private_class_method :apply_big_and_small_of_the_month
|
@@ -159,25 +160,22 @@ module Zakuro
|
|
159
160
|
# 閏月が存在した場合に以降の月を1つずつ減らす
|
160
161
|
# @example 7,8,9 と続く月の8月が閏の場合、7, 閏7, 8 となる
|
161
162
|
#
|
162
|
-
# @param [Array<Month>]
|
163
|
+
# @param [Array<Month>] annual_range 1年データ
|
163
164
|
#
|
164
|
-
def self.adjust_leap_month(
|
165
|
+
def self.adjust_leap_month(annual_range:)
|
165
166
|
# 閏による月の再調整を行う
|
166
167
|
leaped = false
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
168
|
+
annual_range.each_with_index do |month, index|
|
169
|
+
month.eval_leaped
|
170
|
+
# NOTE: 初回閏月(閏11月)は前回月が存在しないため調整外
|
171
|
+
leaped = true if month.leaped? && !index.zero?
|
172
|
+
|
172
173
|
next unless leaped
|
173
174
|
|
174
175
|
# NOTE: 常気法では閏月は2-3年に一度のため、1年に二度発生しない前提
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
number = 12
|
179
|
-
end
|
180
|
-
month.number = number
|
176
|
+
|
177
|
+
# 閏の分だけ1ヶ月ずらす
|
178
|
+
month.back_to_last_month
|
181
179
|
end
|
182
180
|
end
|
183
181
|
private_class_method :adjust_leap_month
|
@@ -0,0 +1,324 @@
|
|
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
|
+
|
8
|
+
require_relative '../base/year'
|
9
|
+
|
10
|
+
# :nodoc:
|
11
|
+
module Zakuro
|
12
|
+
# :nodoc:
|
13
|
+
module Senmyou
|
14
|
+
# FullRange 完全範囲
|
15
|
+
# ある日からある日の範囲を計算可能な年月範囲
|
16
|
+
# * 前提として元号年はその元号の開始年から数える
|
17
|
+
# * ある日の元号年を求める場合、その元号が含まれる最初の年まで遡る
|
18
|
+
# * 元号は一つとは限らない。南北朝などで二つある場合は、古い方の元号から求める
|
19
|
+
#
|
20
|
+
# NOTE: 割り当てた元号は年初を基準にした元号年である
|
21
|
+
# * 元旦を基準にした時の正しい元号を設定している
|
22
|
+
# * 引き当てたい日付が元旦ではない場合、その月日に従い元号を再度求める
|
23
|
+
# * この再計算が必要になるのは、元号が切り替わる年のみである
|
24
|
+
class FullRange
|
25
|
+
# @return [Western::Calendar] 開始日
|
26
|
+
attr_reader :start_date
|
27
|
+
# @return [Western::Calendar] 終了日
|
28
|
+
attr_reader :end_date
|
29
|
+
# @return [MultiGengouRoller] 改元処理
|
30
|
+
attr_reader :multi_gengou_roller
|
31
|
+
# @return [Western::Calendar] 最過去の元旦
|
32
|
+
attr_reader :new_year_date
|
33
|
+
# @return [Integer] 西暦年
|
34
|
+
attr_reader :western_year
|
35
|
+
|
36
|
+
# @return [Logger] ロガー
|
37
|
+
LOGGER = Logger.new(location: 'full_range')
|
38
|
+
|
39
|
+
#
|
40
|
+
# 初期化
|
41
|
+
#
|
42
|
+
# @param [Western::Calendar] start_date 開始日
|
43
|
+
# @param [Western::Calendar] end_date 終了日
|
44
|
+
#
|
45
|
+
def initialize(start_date: Western::Calendar.new, end_date: Western::Calendar.new)
|
46
|
+
@start_date = start_date
|
47
|
+
@end_date = end_date
|
48
|
+
return if invalid?
|
49
|
+
|
50
|
+
@multi_gengou_roller = MultiGengouRoller.new(start_date: start_date, end_date: end_date)
|
51
|
+
@new_year_date = @multi_gengou_roller.oldest_date.clone
|
52
|
+
@western_year = @new_year_date.year
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# 無効か
|
57
|
+
#
|
58
|
+
# @return [True] 無効
|
59
|
+
# @return [False] 有効
|
60
|
+
#
|
61
|
+
def invalid?
|
62
|
+
@start_date.invalid?
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# 完全範囲を取得する
|
67
|
+
#
|
68
|
+
# @return [Array<Year>] 完全範囲
|
69
|
+
#
|
70
|
+
def get
|
71
|
+
return [] if invalid?
|
72
|
+
|
73
|
+
pre_get
|
74
|
+
|
75
|
+
years = FullRange.rearranged_years(annual_ranges: annual_ranges)
|
76
|
+
years = update_gengou(years: years)
|
77
|
+
years = update_first_day(years: years)
|
78
|
+
|
79
|
+
post_get
|
80
|
+
|
81
|
+
years
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# 取得前処理
|
86
|
+
#
|
87
|
+
def pre_get
|
88
|
+
# FIXME: 別インスタンス変数を定義する方法は改善したい(ディープコピーにするか、get再取得を廃止するか)
|
89
|
+
@new_year_date_ = @new_year_date.clone
|
90
|
+
@multi_gengou_roller_ = @multi_gengou_roller.clone
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# 取得前処理
|
95
|
+
#
|
96
|
+
# 再取得に備えて、カウントアップした日付を元に戻す
|
97
|
+
#
|
98
|
+
def post_get
|
99
|
+
@new_year_date = @new_year_date_
|
100
|
+
@multi_gengou_roller = @multi_gengou_roller_
|
101
|
+
end
|
102
|
+
|
103
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
104
|
+
|
105
|
+
#
|
106
|
+
# 完全範囲内の年データを取得する
|
107
|
+
#
|
108
|
+
# @return [Array<Year>] 年データ(冬至基準)
|
109
|
+
#
|
110
|
+
def annual_ranges
|
111
|
+
oldest_date = @new_year_date
|
112
|
+
newest_date = @multi_gengou_roller.newest_date
|
113
|
+
|
114
|
+
years = []
|
115
|
+
((oldest_date.year)..(newest_date.year + 2)).each do |year|
|
116
|
+
years.push(
|
117
|
+
AnnualRange.collect_annual_range_after_last_november_1st(
|
118
|
+
western_year: year
|
119
|
+
)
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
years
|
124
|
+
end
|
125
|
+
|
126
|
+
#
|
127
|
+
# 完全範囲内の年データの開始月を変更する
|
128
|
+
#
|
129
|
+
# @param [Array<Year>] annual_ranges 年データ(冬至基準)
|
130
|
+
#
|
131
|
+
# @return [Array<Year>] 年データ(元旦基準)
|
132
|
+
#
|
133
|
+
def self.rearranged_years(annual_ranges:)
|
134
|
+
years = []
|
135
|
+
|
136
|
+
(0..(annual_ranges.size - 2)).each do |index|
|
137
|
+
year = rearranged_year(annual_ranges: annual_ranges, index: index)
|
138
|
+
years.push(year)
|
139
|
+
end
|
140
|
+
|
141
|
+
years
|
142
|
+
end
|
143
|
+
|
144
|
+
# :reek:TooManyStatements { max_statements: 8 }
|
145
|
+
|
146
|
+
#
|
147
|
+
# 完全範囲内の年データの元号を開始年基準で更新する
|
148
|
+
#
|
149
|
+
# @param [Array<Year>] years 年データ(元旦基準)
|
150
|
+
#
|
151
|
+
# @return [Array<Year>] 元号更新済み年データ(元旦基準)
|
152
|
+
#
|
153
|
+
def update_gengou(years:)
|
154
|
+
updated_years = []
|
155
|
+
|
156
|
+
nearest_end_date = choise_nearest_end_date
|
157
|
+
|
158
|
+
years.each do |year|
|
159
|
+
next_year(years: updated_years, year: year)
|
160
|
+
|
161
|
+
if @new_year_date > nearest_end_date
|
162
|
+
@multi_gengou_roller.transfer
|
163
|
+
nearest_end_date = choise_nearest_end_date
|
164
|
+
end
|
165
|
+
@multi_gengou_roller.next_year
|
166
|
+
end
|
167
|
+
|
168
|
+
updated_years
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# 月初日の西暦日を更新する
|
173
|
+
#
|
174
|
+
# @param [Array<Year>] years 完全範囲(月初日なし)
|
175
|
+
#
|
176
|
+
# @return [Array<Year>] 完全範囲(月初日あり)
|
177
|
+
#
|
178
|
+
def update_first_day(years:)
|
179
|
+
# TODO: リファクタリング
|
180
|
+
|
181
|
+
result = []
|
182
|
+
|
183
|
+
years.each do |year|
|
184
|
+
new_year_date = year.new_year_date.clone
|
185
|
+
date = new_year_date.clone
|
186
|
+
|
187
|
+
months = []
|
188
|
+
year.months.each do |month|
|
189
|
+
first_day = month.first_day
|
190
|
+
updated_month = Month.new(
|
191
|
+
month_label: month.month_label,
|
192
|
+
first_day: FirstDay.new(remainder: first_day.remainder,
|
193
|
+
western_date: date),
|
194
|
+
solar_terms: month.solar_terms
|
195
|
+
)
|
196
|
+
months.push(updated_month)
|
197
|
+
|
198
|
+
date = date.clone + updated_month.days
|
199
|
+
end
|
200
|
+
|
201
|
+
updated_year = Year.new(
|
202
|
+
multi_gengou: year.multi_gengou, new_year_date: new_year_date,
|
203
|
+
months: months, total_days: year.total_days
|
204
|
+
)
|
205
|
+
|
206
|
+
result.push(updated_year)
|
207
|
+
end
|
208
|
+
|
209
|
+
result
|
210
|
+
end
|
211
|
+
|
212
|
+
#
|
213
|
+
# 当年データを生成する
|
214
|
+
#
|
215
|
+
# @param [Array<Year>] annual_ranges 年データ(冬至基準)
|
216
|
+
# @param [Year] year 対象年
|
217
|
+
#
|
218
|
+
# @return [Year] 当年月ありの対象年
|
219
|
+
#
|
220
|
+
def self.push_current_year(annual_range:, year: Year.new)
|
221
|
+
annual_range.each do |month|
|
222
|
+
next if month.is_last_year
|
223
|
+
|
224
|
+
year.push(month: month)
|
225
|
+
end
|
226
|
+
|
227
|
+
year
|
228
|
+
end
|
229
|
+
|
230
|
+
#
|
231
|
+
# 昨年データを生成する
|
232
|
+
#
|
233
|
+
# @param [Array<Year>] annual_ranges 年データ(冬至基準)
|
234
|
+
# @param [Year] year 対象年
|
235
|
+
#
|
236
|
+
# @return [Year] 昨年月ありの対象年
|
237
|
+
#
|
238
|
+
def self.push_last_year(annual_range:, year: Year.new)
|
239
|
+
annual_range.each do |month|
|
240
|
+
next unless month.is_last_year
|
241
|
+
|
242
|
+
year.push(month: month)
|
243
|
+
end
|
244
|
+
|
245
|
+
year
|
246
|
+
end
|
247
|
+
|
248
|
+
#
|
249
|
+
# 年データの開始月を変更する
|
250
|
+
#
|
251
|
+
# @param [Array<Year>] annual_ranges 年データ(冬至基準)
|
252
|
+
# @param [Integer] index 対象年の要素番号
|
253
|
+
#
|
254
|
+
# @return [Year] 年データ(元旦基準)
|
255
|
+
#
|
256
|
+
def self.rearranged_year(annual_ranges:, index:)
|
257
|
+
current_annual_range = annual_ranges[index]
|
258
|
+
next_annual_range = annual_ranges[index + 1]
|
259
|
+
|
260
|
+
year = push_current_year(annual_range: current_annual_range)
|
261
|
+
push_last_year(annual_range: next_annual_range, year: year)
|
262
|
+
|
263
|
+
year
|
264
|
+
end
|
265
|
+
private_class_method :rearranged_year
|
266
|
+
|
267
|
+
private
|
268
|
+
|
269
|
+
#
|
270
|
+
# 元号処理対象の年を進める
|
271
|
+
#
|
272
|
+
# @param [Array<Year>] years 元号処理済み年データ(元旦基準)
|
273
|
+
# @param [Year] year 元号処理前の年(元旦基準)
|
274
|
+
#
|
275
|
+
def next_year(years:, year:)
|
276
|
+
updated_year = update_year(year: year)
|
277
|
+
|
278
|
+
years.push(updated_year)
|
279
|
+
|
280
|
+
next_new_year_date(total_days: updated_year.total_days)
|
281
|
+
|
282
|
+
nil
|
283
|
+
end
|
284
|
+
|
285
|
+
#
|
286
|
+
# 年の元号を更新する
|
287
|
+
#
|
288
|
+
# @param [Year] year 元号処理前の年(元旦基準)
|
289
|
+
#
|
290
|
+
# @return [Year] 元号処理済の年(元旦基準)
|
291
|
+
#
|
292
|
+
def update_year(year:)
|
293
|
+
multi_gengou = @multi_gengou_roller.multi_gengou.clone
|
294
|
+
|
295
|
+
updated_year = Year.new(multi_gengou: multi_gengou, new_year_date: @new_year_date.clone,
|
296
|
+
months: year.months)
|
297
|
+
updated_year.commit
|
298
|
+
|
299
|
+
updated_year
|
300
|
+
end
|
301
|
+
|
302
|
+
#
|
303
|
+
# 次の年に進める
|
304
|
+
#
|
305
|
+
# @param [Integer] total_days 年の日数
|
306
|
+
#
|
307
|
+
def next_new_year_date(total_days:)
|
308
|
+
@new_year_date += total_days
|
309
|
+
@multi_gengou_roller.next(days: total_days)
|
310
|
+
|
311
|
+
nil
|
312
|
+
end
|
313
|
+
|
314
|
+
#
|
315
|
+
# 現在日からみて直近の未来に対する元号の切替前日を求める
|
316
|
+
#
|
317
|
+
# @return [Western::Calendar] 元号の切替前日
|
318
|
+
#
|
319
|
+
def choise_nearest_end_date
|
320
|
+
@multi_gengou_roller.choise_nearest_end_date
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|