zakuro 0.6.0 → 0.6.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -3
  3. data/VERSION +1 -1
  4. data/lib/zakuro/calculation/base/gengou.rb +4 -4
  5. data/lib/zakuro/calculation/base/linear_gengou.rb +6 -6
  6. data/lib/zakuro/calculation/era/gengou/internal/connector.rb +107 -0
  7. data/lib/zakuro/calculation/era/gengou/internal/counter.rb +214 -0
  8. data/lib/zakuro/calculation/era/gengou/internal/publisher.rb +104 -0
  9. data/lib/zakuro/calculation/era/gengou/internal/reserve/list.rb +244 -0
  10. data/lib/zakuro/calculation/era/gengou/internal/reserve/range.rb +193 -0
  11. data/lib/zakuro/calculation/{gengou → era/gengou}/internal/reserve.rb +6 -6
  12. data/lib/zakuro/calculation/{gengou → era/gengou}/scroll.rb +44 -95
  13. data/lib/zakuro/calculation/{version → era/version}/internal/crawler.rb +7 -7
  14. data/lib/zakuro/calculation/{version → era/version}/internal/range.rb +4 -4
  15. data/lib/zakuro/calculation/{version → era/version}/version.rb +3 -3
  16. data/lib/zakuro/calculation/monthly/month.rb +2 -2
  17. data/lib/zakuro/calculation/range/full_range.rb +18 -19
  18. data/lib/zakuro/calculation/range/operated_range.rb +3 -4
  19. data/lib/zakuro/calculation/specifier/internal/month.rb +84 -0
  20. data/lib/zakuro/calculation/specifier/multiple_day.rb +162 -0
  21. data/lib/zakuro/calculation/specifier/single_day.rb +2 -2
  22. data/lib/zakuro/calculation/summary/internal/operation.rb +98 -0
  23. data/lib/zakuro/calculation/summary/range.rb +120 -0
  24. data/lib/zakuro/calculation/summary/single.rb +45 -67
  25. data/lib/zakuro/condition.rb +14 -0
  26. data/lib/zakuro/era/japan/gengou/alignment/aligner.rb +106 -0
  27. data/lib/zakuro/era/japan/gengou/alignment/division.rb +165 -0
  28. data/lib/zakuro/era/japan/gengou/alignment/line.rb +156 -0
  29. data/lib/zakuro/era/japan/gengou/alignment/linear_gengou.rb +184 -0
  30. data/lib/zakuro/era/japan/gengou/alignment.rb +42 -0
  31. data/lib/zakuro/era/japan/gengou/resource/parser.rb +242 -0
  32. data/lib/zakuro/era/japan/gengou/resource/type.rb +292 -0
  33. data/lib/zakuro/era/japan/gengou/resource/validator.rb +346 -0
  34. data/lib/zakuro/era/japan/gengou/{yaml → resource/yaml}/set-001-until-south.yaml +2 -2
  35. data/lib/zakuro/era/japan/gengou/{yaml → resource/yaml}/set-002-from-north.yaml +2 -2
  36. data/lib/zakuro/era/japan/gengou/{yaml → resource/yaml}/set-003-modern.yaml +2 -2
  37. data/lib/zakuro/era/japan/gengou/resource.rb +32 -0
  38. data/lib/zakuro/era/japan/gengou.rb +34 -73
  39. data/lib/zakuro/era/japan/version.rb +18 -18
  40. data/lib/zakuro/merchant.rb +41 -3
  41. data/lib/zakuro/operation/month/validator.rb +1 -1
  42. data/lib/zakuro/result/result.rb +17 -0
  43. data/lib/zakuro/version/senmyou/README.md +11 -7
  44. metadata +32 -20
  45. data/lib/zakuro/calculation/gengou/internal/counter.rb +0 -129
  46. data/lib/zakuro/calculation/gengou/internal/reserve/interval.rb +0 -183
  47. data/lib/zakuro/calculation/gengou/internal/reserve/list.rb +0 -382
  48. data/lib/zakuro/era/japan/gengou/parser.rb +0 -237
  49. data/lib/zakuro/era/japan/gengou/type.rb +0 -285
  50. data/lib/zakuro/era/japan/gengou/validator.rb +0 -341
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './division'
4
+
5
+ require_relative './linear_gengou'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ # :nodoc:
10
+ module Japan
11
+ # :nodoc:
12
+ module Alignment
13
+ #
14
+ # Line 行
15
+ #
16
+ class Line
17
+ # @return [Array<LinearGengou>] 元号
18
+ attr_reader :list
19
+
20
+ #
21
+ # 初期化
22
+ #
23
+ def initialize
24
+ @list = []
25
+ end
26
+
27
+ #
28
+ # 追加する
29
+ #
30
+ # 下記のパターンが存在し、戻り値は重複分となる
31
+ #
32
+ # 1. 完全に範囲外(開始日より前)
33
+ # [@list]: |-------|-------|
34
+ # [list]: |---|
35
+ # 2. 前半のみ範囲外
36
+ # [@list]: |-------|-------|
37
+ # [list]: |------|
38
+ # 3. 範囲内
39
+ # [@list]: |-------|-------|
40
+ # [list]: |------|
41
+ # 4. 後半のみ範囲外
42
+ # [@list]: |-------|-------|
43
+ # [list]: |------|
44
+ # 5. 完全に範囲外(開始日より後)
45
+ # [@list]: |-------|-------|
46
+ # [list]: |----|
47
+ # 6. 両端が範囲外
48
+ # [@list]: |-------|-------|
49
+ # [list]: |--------------------|
50
+ #
51
+ # @param [Array<LinearGengou>] list 元号
52
+ #
53
+ # @return [Array<LinearGengou>] 未登録元号
54
+ #
55
+ def push(list: [])
56
+ rest = rest(list: list)
57
+
58
+ insert(list: list)
59
+
60
+ rest
61
+ end
62
+
63
+ #
64
+ # 範囲内の元号を取得する
65
+ #
66
+ # @param [Western::Calendar] start_date 開始日
67
+ # @param [Western::Calendar] last_date 終了日
68
+ #
69
+ # @return [Array<LinearGengou>] 元号
70
+ #
71
+ def get(start_date:, last_date:)
72
+ result = []
73
+ @list.each do |gengou|
74
+ next if gengou.out?(start_date: start_date, last_date: last_date)
75
+
76
+ # 1日でも範囲内であれば対象とみなす
77
+ result.push(gengou)
78
+ end
79
+
80
+ result
81
+ end
82
+
83
+ private
84
+
85
+ #
86
+ # 重複分(空きがないため追加できない範囲の元号)を返す
87
+ #
88
+ # @param [Array<LinearGengou>] list 元号
89
+ #
90
+ # @return [Array<LinearGengou>] 重複分元号
91
+ #
92
+ def rest(list: [])
93
+ result = []
94
+
95
+ @list.each do |gengou|
96
+ result |= and!(rest: list, other: gengou)
97
+ end
98
+
99
+ Division.connect(list: result)
100
+ end
101
+
102
+ #
103
+ # 空き範囲に元号を登録する
104
+ #
105
+ # @param [Array<LinearGengou>] list 元号
106
+ #
107
+ def insert(list: [])
108
+ surplus_result = list.clone
109
+ @list.each do |gengou|
110
+ surplus_result = not!(surplus: surplus_result, other: gengou)
111
+ end
112
+
113
+ surplus_result = Division.connect(list: surplus_result)
114
+
115
+ surplus_result.each do |gengou|
116
+ @list.push(gengou)
117
+ end
118
+ end
119
+
120
+ #
121
+ # 重複した範囲を返す
122
+ #
123
+ # @param [Array<LinearGengou>] rest 残り元号
124
+ # @param [LinearGengou] other 比較元号
125
+ #
126
+ # @return [Array<LinearGengou>] 重複分
127
+ #
128
+ def and!(rest:, other:)
129
+ result = []
130
+ rest.each do |gengou|
131
+ result |= Division.match(this: gengou, other: other)
132
+ end
133
+
134
+ result
135
+ end
136
+
137
+ #
138
+ # 範囲が重複しない差分を返す
139
+ #
140
+ # @param [Array<LinearGengou>] surplus 積元号
141
+ # @param [LinearGengou] other 比較元号
142
+ #
143
+ # @return [Array<LinearGengou>] 差分
144
+ #
145
+ def not!(surplus:, other:)
146
+ result = []
147
+ surplus.each do |gengou|
148
+ result |= Division.mismatch(this: gengou, other: other)
149
+ end
150
+
151
+ result
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../western/calendar'
4
+
5
+ require_relative '../resource/type'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ # :nodoc:
10
+ module Japan
11
+ # :nodoc:
12
+ module Alignment
13
+ #
14
+ # LinearGengou 直列元号
15
+ #
16
+ class LinearGengou
17
+ INVALID_YEAR = -1
18
+
19
+ # @return [Western::Calendar] 開始日
20
+ attr_reader :start_date
21
+ # @return [Western::Calendar] 終了日
22
+ attr_reader :last_date
23
+ # @return [Gengou] 元号
24
+ attr_reader :gengou
25
+
26
+ #
27
+ # 初期化
28
+ #
29
+ # @param [Western::Calendar] start_date 開始日
30
+ # @param [Western::Calendar] last_date 終了日
31
+ # @param [Resource::Gengou] gengou 元号
32
+ #
33
+ def initialize(start_date: Western::Calendar.new, last_date: Western::Calendar.new,
34
+ gengou: Resource::Gengou.new)
35
+ @gengou = gengou
36
+ @start_date = start_date.invalid? ? native_start_date : start_date
37
+ @last_date = last_date.invalid? ? native_last_date : last_date
38
+ end
39
+
40
+ #
41
+ # 元号名を取得する
42
+ #
43
+ # @return [String] 元号名
44
+ #
45
+ def name
46
+ @gengou.name
47
+ end
48
+
49
+ #
50
+ # 不正か
51
+ #
52
+ # @return [True] 不正
53
+ # @return [False] 不正なし
54
+ #
55
+ def invalid?
56
+ @gengou.invalid?
57
+ end
58
+
59
+ #
60
+ # 範囲内か
61
+ #
62
+ # @param [Western::Calendar] date 西暦日
63
+ #
64
+ # @return [True] 範囲内
65
+ # @return [False] 範囲外
66
+ #
67
+ def include?(date: Western::Calendar.new)
68
+ return false if invalid?
69
+
70
+ return false if @start_date.invalid?
71
+
72
+ return false if @last_date.invalid?
73
+
74
+ return false if date < @start_date
75
+
76
+ return false if date > @last_date
77
+
78
+ true
79
+ end
80
+
81
+ #
82
+ # 完全に範囲内か
83
+ #
84
+ # @param [Western::Calendar] start_date 開始日
85
+ # @param [Western::Calendar] last_date 終了日
86
+ #
87
+ # @return [True] 範囲内
88
+ # @return [False] 範囲外あり
89
+ #
90
+ def in?(start_date:, last_date:)
91
+ @start_date <= start_date && last_date <= @last_date
92
+ end
93
+
94
+ #
95
+ # 完全に範囲外か
96
+ #
97
+ # @param [Western::Calendar] start_date 開始日
98
+ # @param [Western::Calendar] last_date 終了日
99
+ #
100
+ # @return [True] 範囲外
101
+ # @return [False] 範囲内あり
102
+ #
103
+ def out?(start_date:, last_date:)
104
+ # 範囲より前
105
+ return true if start_date < @start_date && last_date < @start_date
106
+
107
+ # 範囲より後
108
+ return true if @last_date < start_date && @last_date < last_date
109
+
110
+ false
111
+ end
112
+
113
+ #
114
+ # 完全に範囲を超えているか
115
+ #
116
+ # @param [Western::Calendar] start_date 開始日
117
+ # @param [Western::Calendar] last_date 終了日
118
+ #
119
+ # @return [True] 完全超過
120
+ # @return [True] 完全超過せず
121
+ #
122
+ def covered?(start_date:, last_date:)
123
+ start_date < @start_date && @last_date < last_date
124
+ end
125
+
126
+ #
127
+ # 元は1繋ぎであった元号が別の行に存在するか(設定値から変更されているか)?
128
+ #
129
+ # @return [True] 存在する
130
+ # @return [False] 存在しない
131
+ #
132
+ def changed?
133
+ return true if change_start_date?
134
+
135
+ return true if change_last_date?
136
+
137
+ false
138
+ end
139
+
140
+ #
141
+ # 開始日が設定された開始日と異なるか(行が変更されているか)
142
+ #
143
+ # @return [True] 異なる
144
+ # @return [False] 同一
145
+ #
146
+ def change_start_date?
147
+ return false if invalid?
148
+
149
+ @start_date != native_start_date
150
+ end
151
+
152
+ #
153
+ # 終了日が設定された終了日と異なるか(行が変更されているか)
154
+ #
155
+ # @return [True] 異なる
156
+ # @return [False] 同一
157
+ #
158
+ def change_last_date?
159
+ return false if invalid?
160
+
161
+ @last_date != native_last_date
162
+ end
163
+
164
+ #
165
+ # 設定された元号の開始日を取得する
166
+ #
167
+ # @return [Western::Calendar]設定された元号の開始日
168
+ #
169
+ def native_start_date
170
+ @gengou.both_start_date.western
171
+ end
172
+
173
+ #
174
+ # 設定された元号の終了日を取得する
175
+ #
176
+ # @return [Western::Calendar] 設定された元号の終了日
177
+ #
178
+ def native_last_date
179
+ @gengou.last_date
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './alignment/aligner'
4
+
5
+ require_relative './resource'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ #
10
+ # Japan 和暦
11
+ #
12
+ module Japan
13
+ #
14
+ # Alignment 整列
15
+ #
16
+ module Alignment
17
+ # @return [Integer] 1行目元号
18
+ FIRST_LINE = Aligner::FIRST_LINE
19
+
20
+ # @return [Integer] 2行目元号
21
+ SECOND_LINE = Aligner::SECOND_LINE
22
+
23
+ # @return [Aligner] 整列結果
24
+ SUMMARY = Aligner.new(resources: Resource::LIST)
25
+
26
+ #
27
+ # 指定した範囲内の元号を取得する
28
+ #
29
+ # @param [Integer] line 行
30
+ # @param [Western::Calendar] start_date 開始日
31
+ # @param [Western::Calendar] last_date 終了日
32
+ #
33
+ # @return [Array<LinearGengou>] 元号
34
+ #
35
+ def self.get(line: FIRST_LINE,
36
+ start_date: Western::Calendar.new, last_date: Western::Calendar.new)
37
+
38
+ SUMMARY.get(line: line, start_date: start_date, last_date: last_date)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,242 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../western/calendar'
4
+ require_relative './type'
5
+ require_relative './validator'
6
+ require 'yaml'
7
+
8
+ # :nodoc:
9
+ module Zakuro
10
+ #
11
+ # Japan 和暦
12
+ #
13
+ module Japan
14
+ #
15
+ # Resource yaml解析結果
16
+ #
17
+ module Resource
18
+ # :reek:TooManyInstanceVariables { max_instance_variables: 5 }
19
+
20
+ #
21
+ # Parser yaml解析
22
+ #
23
+ module Parser
24
+ #
25
+ # GengouParser 元号情報の検証/展開を行う
26
+ #
27
+ class GengouParser
28
+ # @return [Integer] 要素位置
29
+ attr_reader :index
30
+ # @return [String] 元号名
31
+ attr_reader :name
32
+ # @return [Hash<String, String>] 開始年
33
+ attr_reader :both_start_year
34
+ # @return [Hash<String, String>] 開始日
35
+ attr_reader :both_start_date
36
+
37
+ #
38
+ # 初期化
39
+ #
40
+ # @param [Hash<String, Strin>] hash 元号情報
41
+ # @param [Integer] index (元号セット内での)元号の要素位置
42
+ #
43
+ def initialize(hash:, index:)
44
+ @index = index
45
+ @name = hash['name']
46
+ @both_start_year = hash['start_year']
47
+ @both_start_date = hash['start_date']
48
+ end
49
+
50
+ #
51
+ # 元号情報を生成する
52
+ #
53
+ # @return [Gengou] 元号情報
54
+ #
55
+ def create
56
+ both_start_year = Both::YearParser.new(hash: @both_start_year).create
57
+ both_start_date = Both::DateParser.new(hash: @both_start_date).create
58
+
59
+ Gengou.new(name: @name, both_start_year: both_start_year,
60
+ both_start_date: both_start_date)
61
+ end
62
+ end
63
+
64
+ #
65
+ # SetParser 元号セット情報の検証/展開
66
+ #
67
+ class SetParser
68
+ # @return [String] 元号セットID
69
+ attr_reader :id
70
+ # @return [String] 元号セット名
71
+ attr_reader :name
72
+ # @return [Hash<String, String>] 終了年
73
+ attr_reader :both_last_year
74
+ # @return [Hash<String, String>] 終了日
75
+ attr_reader :both_last_date
76
+ # @return [Array<Hash<String, String>>] 元号情報
77
+ attr_reader :list
78
+
79
+ #
80
+ # 初期化
81
+ #
82
+ # @param [Hash<String, Object>] hash 元号セット情報
83
+ #
84
+ def initialize(hash:)
85
+ @id = hash['id']
86
+ @name = hash['name']
87
+ @both_last_year = hash['last_year']
88
+ @both_last_date = hash['last_date']
89
+ @list = hash['list']
90
+ end
91
+
92
+ #
93
+ # 元号セット情報を生成する
94
+ #
95
+ # @return [Set] 元号セット情報
96
+ #
97
+ def create
98
+ both_last_date = Both::DateParser.new(hash: @both_last_date).create
99
+ list = create_list
100
+ Set.new(
101
+ id: @id, name: @name, both_last_date: both_last_date, list: list
102
+ )
103
+ end
104
+
105
+ # :reek:TooManyStatements { max_statements: 7 }
106
+
107
+ #
108
+ # 元号情報を生成する
109
+ #
110
+ # @return [Array<Gengou>] 元号情報
111
+ #
112
+ def create_list
113
+ result = []
114
+ @list.each_with_index do |li, index|
115
+ gengou = GengouParser.new(hash: li, index: index).create
116
+ next_index = index + 1
117
+ gengou = calc_last_date_on_gengou_data(next_index: next_index,
118
+ gengou: gengou)
119
+ result.push(gengou)
120
+ end
121
+
122
+ result
123
+ end
124
+
125
+ # :reek:TooManyStatements { max_statements: 6 }
126
+
127
+ #
128
+ # 次の元号の開始日から、元号の終了日に変換する
129
+ #
130
+ # @param [Integer] next_index 次の元号の要素位置
131
+ # @param [String] gengou 次回開始日
132
+ #
133
+ # @return [Gengou] 元号情報
134
+ #
135
+ def calc_last_date_on_gengou_data(next_index:, gengou:)
136
+ if next_index >= @list.size
137
+ gengou.write_last_year(last_year: @both_last_year['western'])
138
+ last_date = Western::Calendar.parse(str: @both_last_date['western'])
139
+ gengou.write_last_date(last_date: last_date)
140
+ return gengou
141
+ end
142
+ next_item = @list[next_index]
143
+ gengou.convert_next_start_year_to_last_year(
144
+ next_start_year: next_item['start_year']['western']
145
+ )
146
+ gengou.convert_next_start_date_to_last_date(
147
+ next_start_date: next_item['start_date']['western']
148
+ )
149
+ gengou
150
+ end
151
+ end
152
+
153
+ #
154
+ # 和暦/西暦
155
+ #
156
+ module Both
157
+ #
158
+ # YearParser 年
159
+ #
160
+ class YearParser
161
+ # @return [Integer] 和暦元号年
162
+ attr_reader :japan
163
+ # @return [Integer] 西暦年
164
+ attr_reader :western
165
+
166
+ #
167
+ # 初期化
168
+ #
169
+ # @param [Hash<String, Object>] hash 年情報
170
+ #
171
+ def initialize(hash:)
172
+ @japan = hash['japan']
173
+ @western = hash['western']
174
+ end
175
+
176
+ #
177
+ # 年情報を生成する
178
+ #
179
+ # @return [Both::Year] 年情報
180
+ #
181
+ def create
182
+ japan = @japan.to_i
183
+ western = @western.to_i
184
+
185
+ Japan::Resource::Both::Year.new(japan: japan, western: western)
186
+ end
187
+ end
188
+
189
+ #
190
+ # DateParser 日
191
+ #
192
+ class DateParser
193
+ # @return [Japan::Calendar] 和暦日
194
+ attr_reader :japan
195
+ # @return [Western::Calendar] 西暦日
196
+ attr_reader :western
197
+
198
+ #
199
+ # 初期化
200
+ #
201
+ # @param [Hash<String, Object>] hash 日情報
202
+ #
203
+ def initialize(hash:)
204
+ @japan = hash['japan']
205
+ @western = hash['western']
206
+ end
207
+
208
+ #
209
+ # 日情報を生成する
210
+ #
211
+ # @return [Both::Date] 日情報
212
+ #
213
+ def create
214
+ japan = Japan::Calendar.parse(text: @japan)
215
+ western = Western::Calendar.parse(str: @western)
216
+
217
+ Japan::Resource::Both::Date.new(japan: japan, western: western)
218
+ end
219
+ end
220
+ end
221
+
222
+ #
223
+ # 解析/展開する
224
+ #
225
+ # @param [String] filepath 元号セットファイルパス
226
+ #
227
+ # @return [Set] 元号セット情報
228
+ #
229
+ def self.run(filepath: '')
230
+ yaml = YAML.load_file(filepath)
231
+
232
+ failed = Validator.run(yaml_hash: yaml)
233
+
234
+ raise ArgumentError, failed.join("\n") unless failed.empty?
235
+
236
+ parser = SetParser.new(hash: yaml)
237
+ parser.create
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end