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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +4 -0
  3. data/.gitignore +7 -1
  4. data/.rubocop.yml +3 -0
  5. data/Gemfile +2 -0
  6. data/Makefile +2 -0
  7. data/README.md +156 -10
  8. data/Rakefile +1 -1
  9. data/doc/gengou.md +315 -0
  10. data/doc/operation.md +25 -0
  11. data/doc/operation/csv/month.csv +202 -0
  12. data/doc/operation/operation.xlsx +0 -0
  13. data/doc/operation/transfer.rb +77 -0
  14. data/lib/zakuro/condition.rb +19 -15
  15. data/lib/zakuro/cycle/abstract_remainder.rb +3 -4
  16. data/lib/zakuro/era/japan/gengou.rb +106 -0
  17. data/lib/zakuro/era/japan/gengou/parser.rb +167 -0
  18. data/lib/zakuro/era/japan/gengou/type.rb +178 -0
  19. data/lib/zakuro/era/japan/gengou/validator.rb +236 -0
  20. data/lib/zakuro/era/japan/reki.rb +91 -0
  21. data/lib/zakuro/era/japan/yaml/set-001-until-south.yaml +1121 -0
  22. data/lib/zakuro/era/japan/yaml/set-002-from-north.yaml +485 -0
  23. data/lib/zakuro/era/japan/yaml/set-003-modern.yaml +28 -0
  24. data/lib/zakuro/era/western.rb +11 -1
  25. data/lib/zakuro/merchant.rb +3 -1
  26. data/lib/zakuro/operation/month/parser.rb +373 -0
  27. data/lib/zakuro/operation/month/type.rb +458 -0
  28. data/lib/zakuro/operation/month/validator.rb +802 -0
  29. data/lib/zakuro/operation/operation.rb +66 -0
  30. data/lib/zakuro/operation/yaml/month.yaml +6452 -0
  31. data/lib/zakuro/output/error.rb +2 -0
  32. data/lib/zakuro/output/logger.rb +2 -0
  33. data/lib/zakuro/output/response.rb +21 -19
  34. data/lib/zakuro/result/core.rb +52 -0
  35. data/lib/zakuro/result/data.rb +187 -0
  36. data/lib/zakuro/result/operation.rb +114 -0
  37. data/lib/zakuro/result/result.rb +37 -0
  38. data/lib/zakuro/{output → tools}/stringifier.rb +16 -9
  39. data/lib/zakuro/tools/typeof.rb +33 -0
  40. data/lib/zakuro/version.rb +1 -1
  41. data/lib/zakuro/version/senmyou/README.md +3 -1
  42. data/lib/zakuro/version/senmyou/base/era.rb +3 -1
  43. data/lib/zakuro/version/senmyou/base/multi_gengou.rb +98 -0
  44. data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +217 -0
  45. data/lib/zakuro/version/senmyou/base/remainder.rb +4 -4
  46. data/lib/zakuro/version/senmyou/base/solar_term.rb +20 -0
  47. data/lib/zakuro/version/senmyou/base/year.rb +52 -6
  48. data/lib/zakuro/version/senmyou/monthly/first_day.rb +44 -0
  49. data/lib/zakuro/version/senmyou/monthly/initialized_month.rb +48 -0
  50. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +1 -1
  51. data/lib/zakuro/version/senmyou/monthly/month.rb +136 -67
  52. data/lib/zakuro/version/senmyou/monthly/month_label.rb +87 -0
  53. data/lib/zakuro/version/senmyou/monthly/operated_month.rb +167 -0
  54. data/lib/zakuro/version/senmyou/{summary/annual_data.rb → range/annual_range.rb} +38 -40
  55. data/lib/zakuro/version/senmyou/range/full_range.rb +324 -0
  56. data/lib/zakuro/version/senmyou/range/operated_range.rb +126 -0
  57. data/lib/zakuro/version/senmyou/range/operated_solar_terms.rb +181 -0
  58. data/lib/zakuro/version/senmyou/senmyou.rb +2 -2
  59. data/lib/zakuro/version/senmyou/specifier/single_day_specifier.rb +102 -0
  60. data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +1 -1
  61. data/lib/zakuro/version/senmyou/stella/solar_average.rb +54 -32
  62. data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +3 -7
  63. data/lib/zakuro/version/senmyou/summary/single.rb +125 -0
  64. data/lib/zakuro/version_factory.rb +1 -1
  65. metadata +40 -13
  66. data/.travis.yml +0 -6
  67. data/lib/zakuro/era/gengou/set-001-until-south.yaml +0 -375
  68. data/lib/zakuro/era/gengou/set-002-from-north.yaml +0 -166
  69. data/lib/zakuro/era/gengou/set-003-modern.yaml +0 -12
  70. data/lib/zakuro/era/japan.rb +0 -630
  71. data/lib/zakuro/output/result.rb +0 -219
  72. data/lib/zakuro/version/senmyou/base/gengou.rb +0 -210
  73. data/lib/zakuro/version/senmyou/summary/gengou_data.rb +0 -294
@@ -0,0 +1,28 @@
1
+ id: 3
2
+ name: "近代(一世一元)"
3
+ end_date: "9999-12-31"
4
+ list:
5
+ - name: "明治"
6
+ # 1年9月8日
7
+ start_year: 1
8
+ start_date: "1868-10-23"
9
+ new_year_date: "1868-1-25"
10
+ note: ""
11
+ - name: "大正"
12
+ # 1年7月30日
13
+ start_year: 1
14
+ start_date: "1912-7-30"
15
+ new_year_date: "1912-1-1"
16
+ note: ""
17
+ - name: "昭和"
18
+ # 1年12月25日
19
+ start_year: 1
20
+ start_date: "1926-12-25"
21
+ new_year_date: "1926-1-1"
22
+ note: ""
23
+ - name: "令和"
24
+ # 1年5月1日
25
+ start_year: 1
26
+ start_date: "2019-5-1"
27
+ new_year_date: "2019-1-1"
28
+ note: ""
@@ -109,7 +109,7 @@ module Zakuro
109
109
  end
110
110
  end
111
111
 
112
- # :reek:TooManyMethods { max_methods: 17 }
112
+ # :reek:TooManyMethods { max_methods: 18 }
113
113
 
114
114
  #
115
115
  # Calendar 年月日情報(西暦)
@@ -344,6 +344,16 @@ module Zakuro
344
344
  self
345
345
  end
346
346
 
347
+ #
348
+ # 無効値(引数なし)かどうかを検証する
349
+ #
350
+ # @return [True] 無効値
351
+ # @return [False] 無効値以外
352
+ #
353
+ def invalid?
354
+ (@date == Date.new)
355
+ end
356
+
347
357
  #
348
358
  # 年月日をフォーマット化する
349
359
  #
@@ -3,11 +3,13 @@
3
3
  require_relative './version_factory'
4
4
  require_relative './condition'
5
5
 
6
+ require_relative './output/error'
7
+
6
8
  # :nodoc:
7
9
  module Zakuro
8
10
  #
9
11
  # Merchant ざくろ商人
10
- # 東西の暦を取引する
12
+ # 東西の暦を取引する、素敵な笑顔の持ち主
11
13
  #
12
14
  class Merchant
13
15
  # @return [Hash<Symbol, Object>] 条件
@@ -0,0 +1,373 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative '../../era/western'
5
+ require_relative './validator'
6
+ require_relative './type'
7
+
8
+ # :nodoc:
9
+ module Zakuro
10
+ #
11
+ # Operation 運用
12
+ #
13
+ module Operation
14
+ #
15
+ # TypeParser 型ごと変換
16
+ #
17
+ module TypeParser
18
+ #
19
+ # 無効値かを判定する
20
+ #
21
+ # @param [String] str 文字列
22
+ #
23
+ # @return [True] 無効値
24
+ # @return [False] 有効値
25
+ #
26
+ def self.invalid?(str:)
27
+ str == '-'
28
+ end
29
+
30
+ def self.text(str:)
31
+ return '' if invalid?(str: str)
32
+
33
+ str
34
+ end
35
+
36
+ #
37
+ # 有効行を変換する
38
+ #
39
+ # @param [String] str 文字列
40
+ #
41
+ # @return [True] 有効
42
+ # @return [False] 無効
43
+ #
44
+ def self.modified?(str:)
45
+ str == 'true'
46
+ end
47
+
48
+ #
49
+ # 月を変換する
50
+ #
51
+ # @param [String] str 文字列
52
+ #
53
+ # @return [Integer] 月
54
+ #
55
+ def self.month_number(str:)
56
+ return -1 if invalid?(str: str)
57
+
58
+ str.to_i
59
+ end
60
+
61
+ #
62
+ # 閏有無を変換する
63
+ #
64
+ # @param [String] str 文字列
65
+ #
66
+ # @return [True] 閏あり
67
+ # @return [True] 閏なし/閏設定なし
68
+ #
69
+ def self.month_leaped(str:)
70
+ str == 'true'
71
+ end
72
+
73
+ #
74
+ # 西暦日を変換する
75
+ #
76
+ # @param [String] str 文字列
77
+ #
78
+ # @return [Western::Calendar] 西暦日
79
+ #
80
+ def self.western_date(str:)
81
+ return Western::Calendar.new if invalid?(str: str)
82
+
83
+ Western::Calendar.parse(str: str)
84
+ end
85
+
86
+ #
87
+ # 日(差分)を変換する
88
+ #
89
+ # @param [String] str 文字列
90
+ #
91
+ # @return [Integer] 日(差分)
92
+ #
93
+ def self.days(str:)
94
+ return INVALID_DAY_VALUE if invalid?(str: str)
95
+
96
+ str.to_i
97
+ end
98
+
99
+ def self.solar_term_index(str:)
100
+ return -1 if invalid?(str: str)
101
+
102
+ str.to_i
103
+ end
104
+ end
105
+
106
+ #
107
+ # MonthParser 月情報解析(yaml)
108
+ #
109
+ module MonthParser
110
+ #
111
+ # 実行する
112
+ #
113
+ # @return [Array<MonthHistory>] 変更履歴
114
+ #
115
+ def self.run(filepath:)
116
+ hash = YAML.load_file(filepath)
117
+
118
+ failed = Validator.run(yaml_hash: hash)
119
+
120
+ raise ArgumentError, failed.join("\n") unless failed.empty?
121
+
122
+ load(yaml_hash: hash)
123
+ end
124
+
125
+ #
126
+ # 設定ファイルを読み込む
127
+ #
128
+ # @param [Hash] yaml_hash 設定ファイルテキスト
129
+ #
130
+ # @return [Array<MonthHistory>] 変更履歴
131
+ #
132
+ def self.load(yaml_hash: {})
133
+ histories = create_histories(yaml_hash: yaml_hash)
134
+
135
+ annotation_parser = AnnotationParser.new(yaml_hash: yaml_hash)
136
+ annotation_parser.create
137
+
138
+ add_annotations(histories: histories, annotation_parser: annotation_parser)
139
+ end
140
+
141
+ #
142
+ # 変更履歴を読み込む
143
+ #
144
+ # @param [Hash] yaml_hash 設定ファイルテキスト
145
+ #
146
+ # @return [Array<MonthHistory>] 変更履歴
147
+ #
148
+ def self.create_histories(yaml_hash: {})
149
+ result = []
150
+ yaml_hash.each do |month|
151
+ next unless Operation::TypeParser.modified?(str: month['modified'])
152
+
153
+ result.push(
154
+ create_history(yaml_hash: month)
155
+ )
156
+ end
157
+ result
158
+ end
159
+ private_class_method :create_histories
160
+
161
+ def self.create_history(yaml_hash: {})
162
+ diffs = MonthDiffsParser.create(yaml_hash: yaml_hash['diffs'])
163
+
164
+ western_date = Operation::TypeParser.western_date(str: yaml_hash['western_date'])
165
+ reference = Reference.new(page: yaml_hash['page'].to_i, number: yaml_hash['number'].to_i,
166
+ japan_date: yaml_hash['japan_date'])
167
+ MonthHistory.new(id: yaml_hash['id'],
168
+ parent_id: Operation::TypeParser.text(str: yaml_hash['parent_id']),
169
+ reference: reference,
170
+ western_date: western_date,
171
+ diffs: diffs)
172
+ end
173
+ private_class_method :create_history
174
+
175
+ def self.add_annotations(annotation_parser:, histories: [])
176
+ result = []
177
+ histories.each do |history|
178
+ id = history.id
179
+ result.push(
180
+ MonthHistory.new(
181
+ id: id, parent_id: history.parent_id, reference: history.reference,
182
+ western_date: history.western_date,
183
+ annotations: annotation_parser.specify(id: id),
184
+ diffs: history.diffs
185
+ )
186
+ )
187
+ end
188
+
189
+ result
190
+ end
191
+ private_class_method :add_annotations
192
+
193
+ def self.create_history_annnotations(history:, annotations: {}, relations: {})
194
+ history_id = history.id
195
+ history_annotations = []
196
+ [history_id, relations.fetch(history_id, '')].each do |id|
197
+ add_annotation(history_annotations: history_annotations,
198
+ annotations: annotations, id: id)
199
+ end
200
+
201
+ history_annotations
202
+ end
203
+
204
+ def self.add_annotation(history_annotations: [], annotations: {}, id: '')
205
+ annotation = annotations.fetch(id, Annotation.new)
206
+ return if annotation.invalid?
207
+
208
+ history_annotations.push(annotation)
209
+ end
210
+ private_class_method :add_annotation
211
+ end
212
+
213
+ #
214
+ # AnnotationParser 注釈解析
215
+ #
216
+ class AnnotationParser
217
+ # @return [Hash<String, Annotation>] 注釈
218
+ attr_reader :annotations
219
+ # @return [Hash<String, String>] 関連注釈の対応関係
220
+ attr_reader :relations
221
+
222
+ #
223
+ # 初期化
224
+ #
225
+ # @param [Hash] yaml_hash 設定ファイルテキスト
226
+ #
227
+ def initialize(yaml_hash: {})
228
+ @annotations = {}
229
+ @relations = {}
230
+ @yaml_hash = yaml_hash
231
+ end
232
+
233
+ #
234
+ # 注釈を生成する
235
+ #
236
+ def create
237
+ @yaml_hash.each do |month|
238
+ AnnotationParser.resolve_history(
239
+ hash: month, annotations: @annotations, relations: @relations
240
+ )
241
+ end
242
+ end
243
+
244
+ #
245
+ # 月別履歴情報から注釈情報を取り出す
246
+ #
247
+ # @param [<Type>] hash 月別履歴情報yaml
248
+ # @param [Hash<String, Annotation>] annotations 注釈
249
+ # @param [Hash<String, String>] relations 関連注釈の対応関係
250
+ #
251
+ def self.resolve_history(hash: {}, annotations: {}, relations: {})
252
+ id = hash['id']
253
+ annotations[id] = Annotation.new(
254
+ id: id,
255
+ description: Operation::TypeParser.text(str: hash['description']),
256
+ note: Operation::TypeParser.text(str: hash['note'])
257
+ )
258
+ relation_id = hash['relation_id']
259
+
260
+ return if Operation::TypeParser.invalid?(str: relation_id)
261
+
262
+ relations[id] = relation_id
263
+ end
264
+
265
+ #
266
+ # 注釈を特定する
267
+ #
268
+ # @param [String] id ID
269
+ #
270
+ # @return [Array<Annotation>] 注釈
271
+ #
272
+ def specify(id: '')
273
+ ids = [id, relations.fetch(id, '')]
274
+ specify_by_ids(ids: ids)
275
+ end
276
+
277
+ private
278
+
279
+ def specify_by_ids(ids: [])
280
+ annotations = []
281
+ ids.each do |id|
282
+ add_annotation(id: id, annotations: annotations)
283
+ end
284
+
285
+ annotations
286
+ end
287
+
288
+ def add_annotation(id: '', annotations: [])
289
+ annotation = annotation(id: id)
290
+ return if annotation.invalid?
291
+
292
+ annotations.push(annotation)
293
+ end
294
+
295
+ def annotation(id: '')
296
+ @annotations.fetch(id, Annotation.new)
297
+ end
298
+ end
299
+
300
+ #
301
+ # MonthDiffsParser 月情報(差分)解析
302
+ #
303
+ module MonthDiffsParser
304
+ def self.create(yaml_hash: {})
305
+ Diffs.new(
306
+ month: create_month(yaml_hash: yaml_hash['month']),
307
+ solar_term: create_solar_term(yaml_hash: yaml_hash['solar_term']),
308
+ days: Operation::TypeParser.days(str: yaml_hash['days'])
309
+ )
310
+ end
311
+
312
+ def self.create_solar_term(yaml_hash: {})
313
+ SolarTerm::Direction.new(
314
+ source: create_source_solar_term(yaml_hash: yaml_hash['calc']),
315
+ destination: create_destination_solar_term(yaml_hash: yaml_hash['actual']),
316
+ days: Operation::TypeParser.days(str: yaml_hash['days'])
317
+ )
318
+ end
319
+ private_class_method :create_solar_term
320
+
321
+ def self.create_source_solar_term(yaml_hash: {})
322
+ SolarTerm::Source.new(
323
+ index: Operation::TypeParser.solar_term_index(str: yaml_hash['index']),
324
+ to: Operation::TypeParser.western_date(str: yaml_hash['to']),
325
+ zodiac_name: Operation::TypeParser.text(str: yaml_hash['zodiac_name'])
326
+ )
327
+ end
328
+ private_class_method :create_source_solar_term
329
+
330
+ def self.create_destination_solar_term(yaml_hash: {})
331
+ SolarTerm::Destination.new(
332
+ index: Operation::TypeParser.solar_term_index(str: yaml_hash['index']),
333
+ from: Operation::TypeParser.western_date(str: yaml_hash['from']),
334
+ zodiac_name: Operation::TypeParser.text(str: yaml_hash['zodiac_name'])
335
+ )
336
+ end
337
+ private_class_method :create_destination_solar_term
338
+
339
+ def self.create_month(yaml_hash: {})
340
+ Month.new(
341
+ number: create_month_number(yaml_hash: yaml_hash['number']),
342
+ leaped: create_month_leaped(yaml_hash: yaml_hash['leaped']),
343
+ days: create_month_day(yaml_hash: yaml_hash['days'])
344
+ )
345
+ end
346
+ private_class_method :create_month
347
+
348
+ def self.create_month_number(yaml_hash: {})
349
+ Number.new(
350
+ calc: Operation::TypeParser.month_number(str: yaml_hash['calc']),
351
+ actual: Operation::TypeParser.month_number(str: yaml_hash['actual'])
352
+ )
353
+ end
354
+ private_class_method :create_month_number
355
+
356
+ def self.create_month_leaped(yaml_hash: {})
357
+ Leaped.new(
358
+ calc: Operation::TypeParser.month_leaped(str: yaml_hash['calc']),
359
+ actual: Operation::TypeParser.month_leaped(str: yaml_hash['actual'])
360
+ )
361
+ end
362
+ private_class_method :create_month_leaped
363
+
364
+ def self.create_month_day(yaml_hash: {})
365
+ Days.new(
366
+ calc: yaml_hash['calc'],
367
+ actual: yaml_hash['actual']
368
+ )
369
+ end
370
+ private_class_method :create_month_day
371
+ end
372
+ end
373
+ end
@@ -0,0 +1,458 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative '../../era/western'
5
+ require_relative './validator'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ #
10
+ # Operation 運用
11
+ #
12
+ module Operation
13
+ #
14
+ # 日(差分)無効値
15
+ #
16
+ INVALID_DAY_VALUE = -30
17
+
18
+ # :reek:TooManyInstanceVariables { max_instance_variables: 6 }
19
+
20
+ #
21
+ # MonthHistory 変更履歴
22
+ #
23
+ class MonthHistory
24
+ # @return [String] ID
25
+ attr_reader :id
26
+ # @return [String] 親ID
27
+ attr_reader :parent_id
28
+ # @return [Reference] 参照
29
+ attr_reader :reference
30
+ # @return [Western::Calendar] 西暦日
31
+ attr_reader :western_date
32
+ # @return [Array<Annotation>] 注釈
33
+ attr_reader :annotations
34
+ # @return [Diffs] 総差分
35
+ attr_reader :diffs
36
+
37
+ # rubocop:disable Metrics/ParameterLists
38
+ # :reek:LongParameterList { max_params: 6 }
39
+
40
+ #
41
+ # 初期化
42
+ #
43
+ # @param [String] id ID
44
+ # @param [String] parent_id 親ID
45
+ # @param [Reference] reference 参照
46
+ # @param [Western::Calendar] western_date 西暦日
47
+ # @param [Array<Annotation>] annotations 注釈
48
+ # @param [Diffs] diffs 総差分
49
+ #
50
+ def initialize(id: '', parent_id: '', reference: Reference.new,
51
+ western_date: Western::Calendar.new, annotations: [], diffs: Diffs.new)
52
+ @id = id
53
+ @parent_id = parent_id
54
+ @reference = reference
55
+ @western_date = western_date
56
+ @annotations = annotations
57
+ @diffs = diffs
58
+ end
59
+ # rubocop:enable Metrics/ParameterLists
60
+
61
+ #
62
+ # 無効か
63
+ #
64
+ # @return [True] 無効
65
+ # @return [False] 有効
66
+ #
67
+ def invalid?
68
+ id == ''
69
+ end
70
+ end
71
+
72
+ #
73
+ # Annotation 注釈
74
+ #
75
+ class Annotation
76
+ # @return [String] ID
77
+ attr_reader :id
78
+ # @return [String] 内容
79
+ attr_reader :description
80
+ # @return [String] 正誤訂正(zakuro)
81
+ attr_reader :note
82
+
83
+ #
84
+ # 初期化
85
+ #
86
+ # @param [String] id ID
87
+ # @param [String] description 内容
88
+ # @param [String] note 正誤訂正(zakuro)
89
+ #
90
+ def initialize(id: '', description: '', note: '')
91
+ @id = id
92
+ @description = description
93
+ @note = note
94
+ end
95
+
96
+ #
97
+ # 無効か
98
+ #
99
+ # @return [True] 無効
100
+ # @return [False] 有効
101
+ #
102
+ def invalid?
103
+ return true if @id == ''
104
+
105
+ @description == '' && @note == ''
106
+ end
107
+ end
108
+
109
+ #
110
+ # Reference 参照
111
+ #
112
+ class Reference
113
+ # @return [Integer] 頁数
114
+ attr_reader :page
115
+ # @return [Integer] 注釈番号
116
+ attr_reader :number
117
+ # @return [String] 和暦日
118
+ attr_reader :japan_date
119
+
120
+ #
121
+ # 初期化
122
+ #
123
+ # @param [Integer] page 頁数
124
+ # @param [Integer] number 注釈番号
125
+ # @param [String] japan_date 和暦日
126
+ #
127
+ def initialize(page: -1, number: -1, japan_date: '')
128
+ @page = page
129
+ @number = number
130
+ @japan_date = japan_date
131
+ end
132
+
133
+ #
134
+ # 無効か
135
+ #
136
+ # @return [True] 無効
137
+ # @return [False] 有効
138
+ #
139
+ def invalid?
140
+ page == -1
141
+ end
142
+ end
143
+
144
+ #
145
+ # Diffs 総差分
146
+ #
147
+ class Diffs
148
+ # @return [Month] 月差分
149
+ attr_reader :month
150
+ # @return [SolarTerm::Direction] 二十四節気差分
151
+ attr_reader :solar_term
152
+ # @return [Integer] 日差分
153
+ attr_reader :days
154
+
155
+ #
156
+ # 初期化
157
+ #
158
+ # @param [Month] month 月差分
159
+ # @param [SolarTerm::Direction] solar_term 二十四節気差分
160
+ # @param [Integer] days 日差分
161
+ #
162
+ def initialize(month: Month.new, solar_term: SolarTerm::Direction.new,
163
+ days: INVALID_DAY_VALUE)
164
+ @month = month
165
+ @solar_term = solar_term
166
+ @days = days
167
+ end
168
+
169
+ #
170
+ # 日差分が無効か
171
+ #
172
+ # @return [True] 無効
173
+ # @return [False] 有効
174
+ #
175
+ def invalid_days?
176
+ @days == INVALID_DAY_VALUE
177
+ end
178
+ end
179
+
180
+ #
181
+ # Month 月差分
182
+ #
183
+ class Month
184
+ # @return [Number] 月
185
+ attr_reader :number
186
+ # @return [Leaped] 閏有無
187
+ attr_reader :leaped
188
+ # @return [Days] 月の大小
189
+ attr_reader :days
190
+
191
+ # :reek:BooleanParameter
192
+
193
+ #
194
+ # 初期化
195
+ #
196
+ # @param [Number] number 月
197
+ # @param [Leaped] leaped 閏有無
198
+ # @param [Days] days 月の大小
199
+ #
200
+ def initialize(number: Number.new, leaped: Leaped.new, days: Days.new)
201
+ @number = number
202
+ @leaped = leaped
203
+ @days = days
204
+ end
205
+
206
+ #
207
+ # 無効か
208
+ #
209
+ # @return [True] 無効
210
+ # @return [False] 有効
211
+ #
212
+ def invalid?
213
+ number == -1
214
+ end
215
+ end
216
+
217
+ #
218
+ # 二十四節気
219
+ #
220
+ module SolarTerm
221
+ #
222
+ # Direction 二十四節気(移動)
223
+ #
224
+ class Direction
225
+ # @return [Source] 二十四節気(移動元)
226
+ attr_reader :source
227
+ # @return [Destination] 二十四節気(移動先)
228
+ attr_reader :destination
229
+ # @return [Integer] 大余差分
230
+ attr_reader :days
231
+
232
+ #
233
+ # 初期化
234
+ #
235
+ # @param [Source] source 二十四節気(移動元)
236
+ # @param [Destination] destination 二十四節気(移動先)
237
+ # @param [Integer] day 大余差分
238
+ #
239
+ def initialize(source: Source.new, destination: Destination.new,
240
+ days: INVALID_DAY_VALUE)
241
+ @source = source
242
+ @destination = destination
243
+ @days = days
244
+ end
245
+
246
+ #
247
+ # 無効か(大余差分)
248
+ #
249
+ # @return [True] 無効
250
+ # @return [False] 有効
251
+ #
252
+ def invalid_days?
253
+ @days == INVALID_DAY_VALUE
254
+ end
255
+
256
+ #
257
+ # 無効か
258
+ #
259
+ # @return [True] 無効
260
+ # @return [False] 有効
261
+ #
262
+ def invalid?
263
+ @source.invalid? && @destination.invalid?
264
+ end
265
+ end
266
+
267
+ #
268
+ # Source 二十四節気(移動元)
269
+ #
270
+ class Source
271
+ # @return [Integer] 二十四節気番号
272
+ attr_reader :index
273
+ # @return [Western::Calendar] 移動先の月初日
274
+ attr_reader :to
275
+ # @return [String] 十干十二支
276
+ attr_reader :zodiac_name
277
+
278
+ #
279
+ # 初期化
280
+ #
281
+ # @param [Integer] index 二十四節気番号
282
+ # @param [Western::Calendar] to 移動先の月初日
283
+ # @param [String] zodiac_name 十干十二支
284
+ #
285
+ def initialize(index: -1, to: Western::Calendar.new, zodiac_name: '')
286
+ @index = index
287
+ @to = to
288
+ @zodiac_name = zodiac_name
289
+ end
290
+
291
+ #
292
+ # 無効か
293
+ #
294
+ # @return [True] 無効
295
+ # @return [False] 有効
296
+ #
297
+ def invalid?
298
+ @index == -1
299
+ end
300
+ end
301
+
302
+ #
303
+ # Destination 二十四節気(移動先)
304
+ #
305
+ class Destination
306
+ # @return [Integer] 二十四節気番号
307
+ attr_reader :index
308
+ # @return [Western::Calendar] 移動元の月初日
309
+ attr_reader :from
310
+ # @return [String] 十干十二支
311
+ attr_reader :zodiac_name
312
+
313
+ #
314
+ # 初期化
315
+ #
316
+ # @param [Integer] index 二十四節気番号
317
+ # @param [Western::Calendar] from 移動元の月初日
318
+ # @param [String] zodiac_name 十干十二支
319
+ #
320
+ def initialize(index: -1, from: Western::Calendar.new, zodiac_name: '')
321
+ @index = index
322
+ @from = from
323
+ @zodiac_name = zodiac_name
324
+ end
325
+
326
+ #
327
+ # 無効か
328
+ #
329
+ # @return [True] 無効
330
+ # @return [False] 有効
331
+ #
332
+ def invalid?
333
+ @index == -1
334
+ end
335
+ end
336
+ end
337
+
338
+ #
339
+ # Number 月
340
+ #
341
+ class Number
342
+ # @return [Integer] 計算
343
+ attr_reader :calc
344
+ # @return [Integer] 運用
345
+ attr_reader :actual
346
+
347
+ #
348
+ # 初期化
349
+ #
350
+ # @param [Integer] calc 計算
351
+ # @param [Integer] actual 運用
352
+ #
353
+ def initialize(calc: -1, actual: -1)
354
+ @calc = calc
355
+ @actual = actual
356
+ end
357
+
358
+ #
359
+ # 無効か
360
+ #
361
+ # @return [True] 無効
362
+ # @return [False] 有効
363
+ #
364
+ def invalid?
365
+ @calc == -1 || @actual == -1
366
+ end
367
+ end
368
+
369
+ #
370
+ # Leaped 閏有無
371
+ #
372
+ class Leaped
373
+ # @return [True, False] 計算
374
+ attr_reader :calc
375
+ # @return [True, False] 運用
376
+ attr_reader :actual
377
+
378
+ # :reek:BooleanParameter
379
+
380
+ #
381
+ # 初期化
382
+ #
383
+ # @param [True, False] calc 計算
384
+ # @param [True, False] actual 運用
385
+ #
386
+ def initialize(calc: false, actual: false)
387
+ @calc = calc
388
+ @actual = actual
389
+ end
390
+
391
+ #
392
+ # 無効か
393
+ #
394
+ # @return [True] 無効(設定値なし)
395
+ # @return [False] 有効
396
+ #
397
+ def invalid?
398
+ !@calc && !@actual
399
+ end
400
+ end
401
+
402
+ #
403
+ # Days 月大小
404
+ #
405
+ class Days
406
+ # @return [String] 29日
407
+ SMALL = '小'
408
+ # @return [String] 30日
409
+ BIG = '大'
410
+
411
+ # @return [String] 計算
412
+ attr_reader :calc
413
+ # @return [String] 運用
414
+ attr_reader :actual
415
+
416
+ #
417
+ # 初期化
418
+ #
419
+ # @param [String] calc 計算
420
+ # @param [String] actual 運用
421
+ #
422
+ def initialize(calc: '小', actual: '小')
423
+ @calc = calc
424
+ @actual = actual
425
+ end
426
+
427
+ #
428
+ # 計算値が大か
429
+ #
430
+ # @return [True] 大
431
+ # @return [False] 小
432
+ #
433
+ def many_days_calc?
434
+ @calc == BIG
435
+ end
436
+
437
+ #
438
+ # 運用値が大か
439
+ #
440
+ # @return [True] 大
441
+ # @return [False] 小
442
+ #
443
+ def many_days_actual?
444
+ @actual == BIG
445
+ end
446
+
447
+ #
448
+ # 無効か
449
+ #
450
+ # @return [True] 無効(差分なし/設定値なし)
451
+ # @return [False] 有効
452
+ #
453
+ def invalid?
454
+ @calc == @actual
455
+ end
456
+ end
457
+ end
458
+ end