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.
- checksums.yaml +4 -4
- data/VERSION +1 -0
- data/lib/zakuro/calculation/base/gengou.rb +82 -0
- data/lib/zakuro/calculation/base/linear_gengou.rb +76 -0
- data/lib/zakuro/calculation/base/operated_year.rb +5 -15
- data/lib/zakuro/calculation/base/year.rb +26 -14
- data/lib/zakuro/calculation/gengou/internal/counter.rb +129 -0
- data/lib/zakuro/calculation/gengou/internal/reserve/interval.rb +183 -0
- data/lib/zakuro/calculation/gengou/internal/reserve/list.rb +382 -0
- data/lib/zakuro/calculation/gengou/internal/reserve.rb +42 -0
- data/lib/zakuro/calculation/gengou/scroll.rb +262 -0
- data/lib/zakuro/calculation/monthly/first_day.rb +3 -2
- data/lib/zakuro/calculation/monthly/month.rb +49 -2
- data/lib/zakuro/calculation/monthly/operated_month.rb +2 -2
- data/lib/zakuro/calculation/range/full_range.rb +65 -103
- data/lib/zakuro/calculation/range/operated_range.rb +13 -8
- data/lib/zakuro/calculation/range/operated_solar_terms.rb +36 -17
- data/lib/zakuro/calculation/range/transfer/gengou_scroller.rb +54 -0
- data/lib/zakuro/calculation/range/transfer/year_boundary.rb +25 -21
- data/lib/zakuro/calculation/specifier/single_day.rb +13 -35
- data/lib/zakuro/calculation/summary/single.rb +5 -2
- data/lib/zakuro/calculation/version/internal/crawler.rb +51 -0
- data/lib/zakuro/calculation/version/internal/range.rb +39 -0
- data/lib/zakuro/calculation/version/version.rb +24 -0
- data/lib/zakuro/era/japan/calendar.rb +133 -0
- data/lib/zakuro/era/japan/gengou/parser.rb +95 -25
- data/lib/zakuro/era/japan/gengou/type.rb +148 -41
- data/lib/zakuro/era/japan/gengou/validator.rb +157 -52
- data/lib/zakuro/era/japan/gengou/yaml/set-001-until-south.yaml +1870 -0
- data/lib/zakuro/era/japan/gengou/yaml/set-002-from-north.yaml +810 -0
- data/lib/zakuro/era/japan/gengou/yaml/set-003-modern.yaml +50 -0
- data/lib/zakuro/era/japan/gengou.rb +5 -5
- data/lib/zakuro/era/japan/version.rb +151 -0
- data/lib/zakuro/era/{western.rb → western/calendar.rb} +0 -0
- data/lib/zakuro/merchant.rb +12 -3
- data/lib/zakuro/operation/month/parser.rb +1 -1
- data/lib/zakuro/operation/month/type.rb +1 -1
- data/lib/zakuro/operation/month/validator.rb +1 -1
- data/lib/zakuro/output/response.rb +5 -5
- data/lib/zakuro/tools/typeconv.rb +38 -0
- data/lib/zakuro/tools/typeof.rb +4 -1
- data/lib/zakuro/version/context.rb +24 -3
- data/lib/zakuro/version/daien/daien.rb +1 -26
- data/lib/zakuro/version/genka/genka.rb +1 -26
- data/lib/zakuro/version/gihou/gihou.rb +1 -30
- data/lib/zakuro/version/gregorio/gregorio.rb +1 -9
- data/lib/zakuro/version/houryaku/houryaku.rb +1 -9
- data/lib/zakuro/version/joukyou/joukyou.rb +1 -9
- data/lib/zakuro/version/kansei/kansei.rb +1 -9
- data/lib/zakuro/version/senmyou/senmyou.rb +1 -30
- data/lib/zakuro/version/tenpou/tenpou.rb +1 -9
- data/zakuro.gemspec +1 -3
- metadata +25 -17
- data/lib/zakuro/calculation/base/multi_gengou.rb +0 -101
- data/lib/zakuro/calculation/base/multi_gengou_roller.rb +0 -218
- data/lib/zakuro/calculation/range/transfer/western_date_allocation.rb +0 -82
- data/lib/zakuro/era/japan/reki.rb +0 -91
- data/lib/zakuro/era/japan/yaml/set-001-until-south.yaml +0 -1121
- data/lib/zakuro/era/japan/yaml/set-002-from-north.yaml +0 -485
- data/lib/zakuro/era/japan/yaml/set-003-modern.yaml +0 -28
- data/lib/zakuro/version/abstract_version.rb +0 -29
- data/lib/zakuro/version.rb +0 -7
- 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,
|
26
|
+
def initialize(western_date: Western::Calendar.new,
|
27
|
+
remainder: Calculation::Cycle::AbstractRemainder.new)
|
27
28
|
# 西暦日
|
28
29
|
@western_date = western_date
|
29
30
|
# 大余小余
|