zakuro 0.5.0 → 0.6.0

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -0
  3. data/lib/zakuro/calculation/base/gengou.rb +82 -0
  4. data/lib/zakuro/calculation/base/linear_gengou.rb +76 -0
  5. data/lib/zakuro/calculation/base/operated_year.rb +5 -15
  6. data/lib/zakuro/calculation/base/year.rb +26 -14
  7. data/lib/zakuro/calculation/gengou/internal/counter.rb +129 -0
  8. data/lib/zakuro/calculation/gengou/internal/reserve/interval.rb +183 -0
  9. data/lib/zakuro/calculation/gengou/internal/reserve/list.rb +382 -0
  10. data/lib/zakuro/calculation/gengou/internal/reserve.rb +42 -0
  11. data/lib/zakuro/calculation/gengou/scroll.rb +262 -0
  12. data/lib/zakuro/calculation/monthly/first_day.rb +3 -2
  13. data/lib/zakuro/calculation/monthly/month.rb +49 -2
  14. data/lib/zakuro/calculation/monthly/operated_month.rb +2 -2
  15. data/lib/zakuro/calculation/range/full_range.rb +65 -103
  16. data/lib/zakuro/calculation/range/operated_range.rb +13 -8
  17. data/lib/zakuro/calculation/range/operated_solar_terms.rb +36 -17
  18. data/lib/zakuro/calculation/range/transfer/gengou_scroller.rb +54 -0
  19. data/lib/zakuro/calculation/range/transfer/year_boundary.rb +25 -21
  20. data/lib/zakuro/calculation/specifier/single_day.rb +13 -35
  21. data/lib/zakuro/calculation/summary/single.rb +5 -2
  22. data/lib/zakuro/calculation/version/internal/crawler.rb +51 -0
  23. data/lib/zakuro/calculation/version/internal/range.rb +39 -0
  24. data/lib/zakuro/calculation/version/version.rb +24 -0
  25. data/lib/zakuro/era/japan/calendar.rb +133 -0
  26. data/lib/zakuro/era/japan/gengou/parser.rb +95 -25
  27. data/lib/zakuro/era/japan/gengou/type.rb +148 -41
  28. data/lib/zakuro/era/japan/gengou/validator.rb +157 -52
  29. data/lib/zakuro/era/japan/gengou/yaml/set-001-until-south.yaml +1870 -0
  30. data/lib/zakuro/era/japan/gengou/yaml/set-002-from-north.yaml +810 -0
  31. data/lib/zakuro/era/japan/gengou/yaml/set-003-modern.yaml +50 -0
  32. data/lib/zakuro/era/japan/gengou.rb +5 -5
  33. data/lib/zakuro/era/japan/version.rb +151 -0
  34. data/lib/zakuro/era/{western.rb → western/calendar.rb} +0 -0
  35. data/lib/zakuro/merchant.rb +12 -3
  36. data/lib/zakuro/operation/month/parser.rb +1 -1
  37. data/lib/zakuro/operation/month/type.rb +1 -1
  38. data/lib/zakuro/operation/month/validator.rb +1 -1
  39. data/lib/zakuro/output/response.rb +5 -5
  40. data/lib/zakuro/tools/typeconv.rb +38 -0
  41. data/lib/zakuro/tools/typeof.rb +4 -1
  42. data/lib/zakuro/version/context.rb +24 -3
  43. data/lib/zakuro/version/daien/daien.rb +1 -26
  44. data/lib/zakuro/version/genka/genka.rb +1 -26
  45. data/lib/zakuro/version/gihou/gihou.rb +1 -30
  46. data/lib/zakuro/version/gregorio/gregorio.rb +1 -9
  47. data/lib/zakuro/version/houryaku/houryaku.rb +1 -9
  48. data/lib/zakuro/version/joukyou/joukyou.rb +1 -9
  49. data/lib/zakuro/version/kansei/kansei.rb +1 -9
  50. data/lib/zakuro/version/senmyou/senmyou.rb +1 -30
  51. data/lib/zakuro/version/tenpou/tenpou.rb +1 -9
  52. data/zakuro.gemspec +1 -3
  53. metadata +25 -17
  54. data/lib/zakuro/calculation/base/multi_gengou.rb +0 -101
  55. data/lib/zakuro/calculation/base/multi_gengou_roller.rb +0 -218
  56. data/lib/zakuro/calculation/range/transfer/western_date_allocation.rb +0 -82
  57. data/lib/zakuro/era/japan/reki.rb +0 -91
  58. data/lib/zakuro/era/japan/yaml/set-001-until-south.yaml +0 -1121
  59. data/lib/zakuro/era/japan/yaml/set-002-from-north.yaml +0 -485
  60. data/lib/zakuro/era/japan/yaml/set-003-modern.yaml +0 -28
  61. data/lib/zakuro/version/abstract_version.rb +0 -29
  62. data/lib/zakuro/version.rb +0 -7
  63. data/lib/zakuro/version_factory.rb +0 -59
@@ -0,0 +1,382 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../era/japan/gengou'
4
+ require_relative '../../../../era/japan/calendar'
5
+ require_relative '../../../../era/western/calendar'
6
+
7
+ require_relative '../counter'
8
+
9
+ # :nodoc:
10
+ module Zakuro
11
+ # :nodoc:
12
+ module Calculation
13
+ # :nodoc:
14
+ module Gengou
15
+ # :nodoc:
16
+ module Reserve
17
+ # List
18
+ #
19
+ # 予約元号一覧
20
+ #
21
+ class List
22
+ # TODO: refactor
23
+
24
+ # @return [Integer] 不正年
25
+ INVALID_YEAR = -1
26
+ # @return [Integer] 最大試行数
27
+ MAX_SEARCH_COUNT = 10_000
28
+ # @return [Integer] 最大月日数
29
+ MAX_MONTH_DAYS = 30
30
+
31
+ # @return [Symbol] メソッド名
32
+ attr_reader :method_name
33
+ # @return [Western::Calendar] 開始日
34
+ attr_reader :start_date
35
+ # @return [Western::Calendar] 終了日
36
+ attr_reader :end_date
37
+ # @return [Array<Japan::Gengou>] 予約元号一覧
38
+ attr_reader :list
39
+
40
+ #
41
+ # 初期化
42
+ #
43
+ # @param [True, False] first true:1行目元号, false:2行目元号
44
+ # @param [Western::Calendar] start_date 開始日
45
+ # @param [Western::Calendar] end_date 終了日
46
+ #
47
+ def initialize(first: true, start_date: Western::Calendar.new,
48
+ end_date: Western::Calendar)
49
+ @method_name = first ? :first_line : :second_line
50
+ @start_date = start_date
51
+ @end_date = end_date
52
+ @list = []
53
+
54
+ update
55
+ end
56
+
57
+ #
58
+ # 元号を取得する
59
+ #
60
+ # @param [Western::Calendar] western_date 西暦日
61
+ #
62
+ # @return [Gengou::Counter] 加算元号
63
+ #
64
+ def get(western_date: Western::Calendar.new)
65
+ @list.each do |gengou|
66
+ if gengou.include?(date: western_date)
67
+ return Gengou::Counter.new(gengou: gengou).clone
68
+ end
69
+ end
70
+
71
+ Gengou::Counter.new
72
+ end
73
+
74
+ #
75
+ # 範囲内元号を取得する
76
+ #
77
+ # 次のパターンが考えられる
78
+ # 1. 元号の開始日から終了日まで該当元号なし(無効な元号)
79
+ # 2. 元号の開始日までは該当元号なし(無効な元号、開始日以降の元号)
80
+ # 3. 元号の開始日と月初日が合致し、末日まで同一元号(開始日以降の元号のみ)
81
+ # 4. 月の途中で有効な元号が切り替わる(有効な元号、有効な元号...)
82
+ # 5. 途中から該当元号なし(開始日以降の元号、無効な元号)
83
+ #
84
+ # FIXME: 有効な元号、無効な元号、有効な元号のようなストライプのパターンに対応していない
85
+ #
86
+ # @param [Western::Calendar] start_date 西暦開始日
87
+ # @param [Western::Calendar] end_date 西暦終了日
88
+ #
89
+ # @return [Array<Gengou::Counter>] 範囲内元号
90
+ #
91
+ def collect(start_date: Western::Calendar.new, end_date: Western::Calendar.new)
92
+ result = []
93
+
94
+ # 開始チェック
95
+ current_gengou = get(western_date: start_date)
96
+ result.push(current_gengou)
97
+
98
+ ## 範囲内に次の有効元号があるか
99
+ if current_gengou.invalid?
100
+ current_gengou = proceed(western_date: start_date)
101
+
102
+ return result if suspend?(current_gengou: current_gengou, end_date: end_date)
103
+
104
+ result.push(current_gengou)
105
+ end
106
+
107
+ return result if suspend?(current_gengou: current_gengou, end_date: end_date)
108
+
109
+ # 有効元号チェック
110
+ continue(result: result, current_date: current_gengou.western_end_date.clone,
111
+ end_date: end_date)
112
+ end
113
+
114
+ #
115
+ # 元号を進めて取得する
116
+ #
117
+ # @param [Western::Calendar] western_date 西暦日
118
+ #
119
+ # @return [Gengou::Counter] 加算元号
120
+ #
121
+ def proceed(western_date: Western::Calendar.new)
122
+ current_gengou = get(western_date: western_date)
123
+
124
+ # 無効な元号
125
+ if current_gengou.invalid?
126
+ @list.each do |gengou|
127
+ next if gengou.invalid?
128
+
129
+ # すでに超過している場合
130
+ break if western_date > gengou.end_date
131
+
132
+ return Gengou::Counter.new(gengou: gengou).clone
133
+ end
134
+
135
+ return Gengou::Counter.new
136
+ end
137
+
138
+ # 有効な元号
139
+ @list.each do |gengou|
140
+ next if gengou.invalid?
141
+
142
+ if gengou.both_start_date.western > current_gengou.western_end_date
143
+ return Gengou::Counter.new(gengou: gengou).clone
144
+ end
145
+ end
146
+
147
+ Gengou::Counter.new
148
+ end
149
+
150
+ #
151
+ # 和暦開始日を取得する
152
+ #
153
+ # @return [Japan::Calendar] 和暦開始日
154
+ #
155
+ def japan_start_date
156
+ return Japan::Calendar.new if invalid?
157
+
158
+ @list[0].both_start_date.japan.clone
159
+ end
160
+
161
+ #
162
+ # 西暦開始日を取得する
163
+ #
164
+ # @return [Western::Calendar] 西暦開始日
165
+ #
166
+ def western_start_date
167
+ return Western::Calendar.new if invalid?
168
+
169
+ @list[0].both_start_date.western.clone
170
+ end
171
+
172
+ #
173
+ # 西暦開始年を取得する
174
+ #
175
+ # @return [Integer] 西暦開始年
176
+ #
177
+ def western_start_year
178
+ return INVALID_YEAR if invalid?
179
+
180
+ @list[0].both_start_year.western.clone
181
+ end
182
+
183
+ #
184
+ # 西暦終了年を取得する
185
+ #
186
+ # @return [Integer] 西暦終了年
187
+ #
188
+ def western_end_year
189
+ return INVALID_YEAR if invalid?
190
+
191
+ return INVALID_YEAR if @list.size.zero?
192
+
193
+ @list[-1].end_year
194
+ end
195
+
196
+ #
197
+ # 不正か
198
+ #
199
+ # @return [True] 不正
200
+ # @return [False] 不正なし
201
+ #
202
+ def invalid?
203
+ return true unless @list
204
+
205
+ return true if @list.size.zero?
206
+
207
+ false
208
+ end
209
+
210
+ private
211
+
212
+ #
213
+ # 予約元号一覧を更新する
214
+ #
215
+ def update
216
+ result = internal
217
+
218
+ return result if result.size.zero?
219
+
220
+ prev_gengou(list: result)
221
+
222
+ next_gengou(list: result)
223
+
224
+ @list = result
225
+ end
226
+
227
+ #
228
+ # 開始日・終了日に対応する予約元号一覧を取得する
229
+ #
230
+ # @return [Array<Japan::Gengou>] 予約元号一覧
231
+ #
232
+ def internal
233
+ current_gengou = line(date: start_date)
234
+ result = []
235
+
236
+ return result if current_gengou.invalid?
237
+
238
+ result.push(current_gengou)
239
+ (0..MAX_SEARCH_COUNT).each do |_index|
240
+ current_end_date = current_gengou.end_date.clone
241
+ break if current_end_date > end_date
242
+
243
+ current_gengou = line(date: current_end_date + 1)
244
+ result.push(current_gengou)
245
+ end
246
+
247
+ result
248
+ end
249
+
250
+ #
251
+ # 前の元号を設定する
252
+ #
253
+ # @note 開始日の30日前に前の元号がある場合は、前の元号を設定する
254
+ #
255
+ # @param [Array<Japan::Gengou>] list 元号一覧
256
+ #
257
+ def prev_gengou(list:)
258
+ return unless list
259
+
260
+ return if list.size.zero?
261
+
262
+ first_gengou_date = list[0].both_start_date.western.clone
263
+
264
+ border_date = start_date.clone - MAX_MONTH_DAYS
265
+
266
+ return if first_gengou_date < border_date
267
+
268
+ gengou = line(date: first_gengou_date - 1)
269
+
270
+ return if gengou.invalid?
271
+
272
+ list.unshift(gengou)
273
+ end
274
+
275
+ #
276
+ # 次の元号を設定する
277
+ #
278
+ # @note 開始日の30日後に次の元号がある場合は、次の元号を設定する
279
+ #
280
+ # @param [Array<Japan::Gengou>] list 元号一覧
281
+ #
282
+ def next_gengou(list:)
283
+ return unless list
284
+
285
+ return if list.size.zero?
286
+
287
+ last_gengou_date = list[-1].end_date.clone
288
+
289
+ border_date = end_date.clone + MAX_MONTH_DAYS
290
+
291
+ return if border_date < last_gengou_date
292
+
293
+ gengou = line(date: last_gengou_date + 1)
294
+
295
+ return if gengou.invalid?
296
+
297
+ list.push(gengou)
298
+ end
299
+
300
+ #
301
+ # 元号
302
+ #
303
+ # @param [Western::Calendar] date 日付
304
+ #
305
+ # @return [Japan::Gengou] 元号
306
+ #
307
+ def line(date:)
308
+ List.send(method_name, **{ date: date })
309
+ end
310
+
311
+ #
312
+ # 有効元号を継続する
313
+ #
314
+ # @param [Array<Gengou::Counter>] result 範囲内元号
315
+ # @param [Gengou::Counter] current_gengou 現在元号
316
+ # @param [Western::Calendar] end_date 終了日
317
+ #
318
+ # @return [Array<Gengou::Counter>] 範囲内元号
319
+ #
320
+ def continue(result:, current_date:, end_date:)
321
+ (0..MAX_SEARCH_COUNT).each do |_index|
322
+ current_gengou = proceed(western_date: current_date)
323
+
324
+ return result if suspend?(current_gengou: current_gengou, end_date: end_date)
325
+
326
+ # 範囲内元号
327
+ result.push(current_gengou)
328
+
329
+ current_date = current_gengou.western_end_date.clone
330
+ end
331
+
332
+ # 終了
333
+ result
334
+ end
335
+
336
+ #
337
+ # 中断する
338
+ #
339
+ # @param [Gengou::Counter] current_gengou 現在元号
340
+ # @param [Western::Calendar] end_date 終了日
341
+ #
342
+ # @return [True] 中断
343
+ # @return [False] 継続
344
+ #
345
+ def suspend?(current_gengou:, end_date:)
346
+ ## 有効元号なし
347
+ return true if current_gengou.invalid?
348
+
349
+ ## 範囲内元号なし
350
+ return true if current_gengou.western_start_date > end_date
351
+
352
+ false
353
+ end
354
+
355
+ #
356
+ # 1行目元号
357
+ #
358
+ # @param [Western::Calendar] date 日付
359
+ #
360
+ # @return [Japan::Gengou] 1行目元号
361
+ #
362
+ def self.first_line(date:)
363
+ Zakuro::Japan::GengouResource.first_line(date: date)
364
+ end
365
+ private_class_method :first_line
366
+
367
+ #
368
+ # 2行目元号
369
+ #
370
+ # @param [Western::Calendar] date 日付
371
+ #
372
+ # @return [Japan::Gengou] 2行目元号
373
+ #
374
+ def self.second_line(date:)
375
+ Zakuro::Japan::GengouResource.second_line(date: date)
376
+ end
377
+ private_class_method :second_line
378
+ end
379
+ end
380
+ end
381
+ end
382
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../era/western/calendar'
4
+ require_relative './reserve/interval'
5
+ require_relative './reserve/list'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ # :nodoc:
10
+ module Calculation
11
+ # :nodoc:
12
+ module Gengou
13
+ # Reserve
14
+ #
15
+ # 元号に基づき計算範囲を予約する
16
+ #
17
+ module Reserve
18
+ #
19
+ # 予約結果を取得する
20
+ #
21
+ # * 開始日・終了日から計算する範囲を求める
22
+ # * 開始日・終了日の範囲内にある元号全てが対象となる
23
+ # * 元号に応じて計算範囲は変化する
24
+ # * 元号の開始日(改元日)が開始日よりも前であれば、結果開始日は前者になる
25
+ # * 元号の終了日(改元前日)が終了日よりも後であれば、結果終了日は前者になる
26
+ # * 南北朝のように複数元号に属する場合、より広い範囲の元号に合わせる
27
+ # * 属する元号よりもさらに範囲を広げる場合がある
28
+ # * 開始日が最初の元号の改元後30日以内の場合、さらに前の元号まで対象にする
29
+ # * 終了日が最後の元号の改元前日30日以内の場合、さらに次の元号まで対象にする
30
+ #
31
+ # @param [Western::Calendar] start_date 開始日
32
+ # @param [Western::Calendar] end_date 終了日
33
+ #
34
+ # @return [Interval] 予約済み計算範囲
35
+ #
36
+ def self.get(start_date: Western::Calendar.new, end_date: Western::Calendar.new)
37
+ Interval.new(start_date: start_date, end_date: end_date)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,262 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../era/western/calendar'
4
+ require_relative '../base/gengou'
5
+ require_relative '../base/linear_gengou'
6
+ require_relative './internal/reserve/interval'
7
+
8
+ # :nodoc:
9
+ module Zakuro
10
+ # :nodoc:
11
+ module Calculation
12
+ # :nodoc:
13
+ module Gengou
14
+ # Scroll
15
+ #
16
+ # 元号スクロール
17
+ #
18
+ class Scroll
19
+ # @return [Western::Calendar] 月初日
20
+ attr_reader :monthly_start_date
21
+ # @return [Western::Calendar] 月末日
22
+ attr_reader :monthly_end_date
23
+ # @return [Reserve::Interval] 予約範囲
24
+ attr_reader :interval
25
+ # @return [Array<Counte>] 1行目元号
26
+ attr_reader :first_gengou
27
+ # @return [Array<Counte>] 2行目元号
28
+ attr_reader :second_gengou
29
+
30
+ #
31
+ # 初期化
32
+ #
33
+ # @param [Western::Calendar] start_date 西暦開始日(最大範囲)
34
+ # @param [Western::Calendar] end_date 西暦終了日(最大範囲)
35
+ #
36
+ def initialize(start_date: Western::Calendar.new, end_date: Western::Calendar.new)
37
+ @monthly_start_date = Western::Calendar.new
38
+ @monthly_end_date = Western::Calendar.new
39
+ @interval = Reserve::Interval.new(start_date: start_date, end_date: end_date)
40
+ @first_gengou = []
41
+ @second_gengou = []
42
+ @ignited = false
43
+ end
44
+
45
+ #
46
+ # 進める
47
+ #
48
+ # @param [Monthly::Month] month 月
49
+ #
50
+ def run(month:)
51
+ unless @ignited
52
+ # 開始日の検索を行う
53
+ @ignited = ignite(month: month)
54
+ return
55
+ end
56
+
57
+ # 時間を進める
58
+ advance(month: month)
59
+ end
60
+
61
+ #
62
+ # 元号開始を試みる
63
+ #
64
+ # @param [Monthly::Month] month 月
65
+ #
66
+ # @return [True] 開始あり
67
+ # @return [False] 開始なし
68
+ #
69
+ def ignite(month:)
70
+ return false unless ignitable?(month: month)
71
+
72
+ japan_start_date = @interval.japan_start_date
73
+
74
+ western_start_date = @interval.western_start_date
75
+
76
+ # 今月初日(和暦日が1月2日であれば、開始日の1日前が初日)
77
+ @monthly_start_date = western_start_date.clone - japan_start_date.day + 1
78
+
79
+ # 今月末
80
+ @monthly_end_date = @monthly_start_date.clone + month.days - 1
81
+
82
+ update_current_gengou
83
+
84
+ true
85
+ end
86
+
87
+ #
88
+ # 進める
89
+ #
90
+ # @param [Monthly::Month] month 月
91
+ #
92
+ def advance(month:)
93
+ @monthly_start_date = @monthly_end_date.clone + 1
94
+
95
+ @monthly_end_date = @monthly_start_date.clone + month.days - 1
96
+
97
+ next_year if month.number == 1 && !month.leaped?
98
+
99
+ update_current_gengou
100
+ end
101
+
102
+ #
103
+ # 共通の元号に変換する
104
+ #
105
+ # @return [Base::Gengou] 元号
106
+ #
107
+ def to_gengou
108
+ start_date = @monthly_start_date.clone
109
+ end_date = @monthly_end_date.clone
110
+
111
+ Base::Gengou.new(
112
+ start_date: start_date,
113
+ end_date: end_date,
114
+ first_line: to_linear_gengou(
115
+ start_date: start_date, end_date: end_date, gengou_list: @first_gengou
116
+ ),
117
+ second_line: to_linear_gengou(
118
+ start_date: start_date, end_date: end_date, gengou_list: @second_gengou
119
+ )
120
+ )
121
+ end
122
+
123
+ #
124
+ # 開始西暦年を取得する
125
+ #
126
+ # @return [Integer] 開始西暦年
127
+ #
128
+ def western_start_year
129
+ @interval.western_start_year
130
+ end
131
+
132
+ #
133
+ # 終了西暦年を取得する
134
+ #
135
+ # @return [Integer] 終了西暦年
136
+ #
137
+ def western_end_year
138
+ @interval.western_end_year
139
+ end
140
+
141
+ private
142
+
143
+ #
144
+ # 現在月に合わせて元号を更新する
145
+ #
146
+ def update_current_gengou
147
+ start_date = @monthly_start_date
148
+ end_date = @monthly_end_date
149
+ first_gengou = @interval.collect_first_gengou(start_date: start_date, end_date: end_date)
150
+ second_gengou = @interval.collect_second_gengou(start_date: start_date,
151
+ end_date: end_date)
152
+
153
+ @first_gengou = replace_gengou(source: @first_gengou, destination: first_gengou)
154
+ @second_gengou = replace_gengou(source: @second_gengou, destination: second_gengou)
155
+ end
156
+
157
+ #
158
+ # 元号を差し替える
159
+ #
160
+ # @param [Array<Counter>] source 元の元号
161
+ # @param [Array<Counter>] destination 次の元号
162
+ #
163
+ # @return [Array<Counter>] 差し替え結果
164
+ #
165
+ def replace_gengou(source: [], destination: [])
166
+ return destination if destination.size.zero?
167
+
168
+ return destination if source.size.zero?
169
+
170
+ last = source[-1]
171
+ destination[0] = last if destination[0].name == last.name
172
+
173
+ destination
174
+ end
175
+
176
+ #
177
+ # 直列元号に変換する
178
+ #
179
+ # * 最初の元号:開始日~その元号の終了日
180
+ # * 中間の元号:その元号の開始日~その元号の終了日
181
+ # * 最後の元号:その元号の開始日~終了日
182
+ #
183
+ # @param [Western::Calendar] start_date 西暦開始日
184
+ # @param [Western::Calendar] end_date 西暦終了日
185
+ # @param [Array<Counter>] gengou_list 元号リスト
186
+ #
187
+ # @return [Array<Base::Gengou>] 元号リスト
188
+ #
189
+ def to_linear_gengou(start_date:, end_date:, gengou_list: [])
190
+ return [] if gengou_list.size.zero?
191
+
192
+ result = []
193
+
194
+ gengou_list.each do |gengou|
195
+ if gengou.invalid?
196
+ # 無効元号は無効のままにする
197
+ result.push(Base::LinearGengou.new)
198
+ next
199
+ end
200
+
201
+ linear_gengou = to_limited_linear_gengou(
202
+ start_date: start_date,
203
+ end_date: end_date,
204
+ gengou: gengou
205
+ )
206
+ result.push(linear_gengou)
207
+ end
208
+
209
+ result
210
+ end
211
+
212
+ #
213
+ # 範囲を限定した直列元号に変換する
214
+ #
215
+ # * 開始日・終了日により範囲を狭める
216
+ #
217
+ # @param [Western::Calendar] start_date 西暦開始日
218
+ # @param [Western::Calendar] end_date 西暦終了日
219
+ # @param [Counter] gengou 加算元号
220
+ #
221
+ # @return [Base::Gengou] 元号
222
+ #
223
+ def to_limited_linear_gengou(start_date:, end_date:, gengou:)
224
+ gengou_start_date = gengou.western_start_date.clone
225
+ gengou_end_date = gengou.western_end_date.clone
226
+
227
+ gengou_start_date = start_date.clone if start_date > gengou_start_date
228
+ gengou_end_date = end_date.clone if end_date < gengou_end_date
229
+
230
+ Base::LinearGengou.new(
231
+ start_date: gengou_start_date, end_date: gengou_end_date,
232
+ name: gengou.name, year: gengou.japan_year
233
+ )
234
+ end
235
+
236
+ #
237
+ # 開始可能か
238
+ #
239
+ # @param [Monthly::Month] month 月
240
+ #
241
+ # @return [True] 開始可
242
+ # @return [True] 開始不可
243
+ #
244
+ def ignitable?(month:)
245
+ return false unless @monthly_start_date.invalid?
246
+
247
+ japan_start_date = @interval.japan_start_date
248
+
249
+ japan_start_date.same_month?(leaped: month.leaped?, month: month.number)
250
+ end
251
+
252
+ #
253
+ # 次年にする
254
+ #
255
+ def next_year
256
+ @first_gengou.each(&:next_year)
257
+ @second_gengou.each(&:next_year)
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../era/western'
3
+ require_relative '../../era/western/calendar'
4
4
 
5
5
  # :nodoc:
6
6
  module Zakuro
@@ -23,7 +23,8 @@ module Zakuro
23
23
  # @param [Remainder] remainder 西暦日
24
24
  # @param [Western::Calendar] western_date 大余小余
25
25
  #
26
- def initialize(western_date: Western::Calendar.new, remainder:)
26
+ def initialize(western_date: Western::Calendar.new,
27
+ remainder: Calculation::Cycle::AbstractRemainder.new)
27
28
  # 西暦日
28
29
  @western_date = western_date
29
30
  # 大余小余