zakuro 0.0.2 → 0.1.3

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/README.md +102 -42
  4. data/doc/operation.md +25 -0
  5. data/doc/operation/csv/month.csv +202 -0
  6. data/doc/operation/operation.xlsx +0 -0
  7. data/doc/operation/transfer.rb +77 -0
  8. data/lib/zakuro/calculation/base/multi_gengou.rb +101 -0
  9. data/lib/zakuro/calculation/base/multi_gengou_roller.rb +218 -0
  10. data/lib/zakuro/calculation/base/year.rb +107 -0
  11. data/lib/zakuro/calculation/cycle/abstract_remainder.rb +459 -0
  12. data/lib/zakuro/calculation/cycle/abstract_solar_term.rb +151 -0
  13. data/lib/zakuro/calculation/cycle/zodiac.rb +106 -0
  14. data/lib/zakuro/calculation/monthly/first_day.rb +45 -0
  15. data/lib/zakuro/calculation/monthly/initialized_month.rb +120 -0
  16. data/lib/zakuro/calculation/monthly/month.rb +184 -0
  17. data/lib/zakuro/calculation/monthly/month_label.rb +88 -0
  18. data/lib/zakuro/calculation/monthly/operated_month.rb +201 -0
  19. data/lib/zakuro/calculation/range/full_range.rb +210 -0
  20. data/lib/zakuro/calculation/range/operated_range.rb +134 -0
  21. data/lib/zakuro/calculation/range/operated_solar_terms.rb +201 -0
  22. data/lib/zakuro/calculation/range/transfer/western_date_allocation.rb +76 -0
  23. data/lib/zakuro/calculation/range/transfer/year_boundary.rb +142 -0
  24. data/lib/zakuro/calculation/specifier/single_day.rb +109 -0
  25. data/lib/zakuro/calculation/summary/single.rb +129 -0
  26. data/lib/zakuro/condition.rb +17 -13
  27. data/lib/zakuro/era/japan/gengou.rb +106 -0
  28. data/lib/zakuro/era/japan/gengou/parser.rb +167 -0
  29. data/lib/zakuro/era/japan/gengou/type.rb +178 -0
  30. data/lib/zakuro/era/japan/gengou/validator.rb +236 -0
  31. data/lib/zakuro/era/japan/reki.rb +91 -0
  32. data/lib/zakuro/era/{gengou → japan/yaml}/set-001-until-south.yaml +0 -0
  33. data/lib/zakuro/era/{gengou → japan/yaml}/set-002-from-north.yaml +0 -0
  34. data/lib/zakuro/era/{gengou → japan/yaml}/set-003-modern.yaml +1 -1
  35. data/lib/zakuro/era/western.rb +1 -1
  36. data/lib/zakuro/merchant.rb +2 -2
  37. data/lib/zakuro/operation/month/parser.rb +373 -0
  38. data/lib/zakuro/operation/month/type.rb +453 -0
  39. data/lib/zakuro/operation/month/validator.rb +802 -0
  40. data/lib/zakuro/operation/operation.rb +66 -0
  41. data/lib/zakuro/operation/yaml/month.yaml +6452 -0
  42. data/lib/zakuro/output/error.rb +7 -4
  43. data/lib/zakuro/output/logger.rb +50 -47
  44. data/lib/zakuro/output/response.rb +146 -143
  45. data/lib/zakuro/result/core.rb +52 -0
  46. data/lib/zakuro/result/data.rb +187 -0
  47. data/lib/zakuro/result/operation.rb +114 -0
  48. data/lib/zakuro/result/result.rb +37 -0
  49. data/lib/zakuro/{output → tools}/stringifier.rb +16 -9
  50. data/lib/zakuro/tools/typeof.rb +33 -0
  51. data/lib/zakuro/version.rb +1 -1
  52. data/lib/zakuro/version/abstract_version.rb +1 -1
  53. data/lib/zakuro/version/context.rb +23 -0
  54. data/lib/zakuro/version/senmyou/cycle/remainder.rb +63 -0
  55. data/lib/zakuro/version/senmyou/cycle/solar_term.rb +31 -0
  56. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +186 -182
  57. data/lib/zakuro/version/senmyou/range/annual_range.rb +164 -0
  58. data/lib/zakuro/version/senmyou/senmyou.rb +10 -4
  59. data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +7 -7
  60. data/lib/zakuro/version/senmyou/stella/solar_average.rb +103 -138
  61. data/lib/zakuro/version/senmyou/stella/solar_location.rb +213 -0
  62. data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +6 -191
  63. data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +4 -4
  64. data/lib/zakuro/version/version_class_resolver.rb +62 -0
  65. data/lib/zakuro/version_factory.rb +3 -3
  66. metadata +49 -20
  67. data/lib/zakuro/cycle/abstract_remainder.rb +0 -457
  68. data/lib/zakuro/cycle/zodiac.rb +0 -103
  69. data/lib/zakuro/era/japan.rb +0 -660
  70. data/lib/zakuro/output/result.rb +0 -219
  71. data/lib/zakuro/version/senmyou/base/era.rb +0 -83
  72. data/lib/zakuro/version/senmyou/base/multi_gengou.rb +0 -98
  73. data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +0 -205
  74. data/lib/zakuro/version/senmyou/base/remainder.rb +0 -60
  75. data/lib/zakuro/version/senmyou/base/solar_term.rb +0 -66
  76. data/lib/zakuro/version/senmyou/base/year.rb +0 -104
  77. data/lib/zakuro/version/senmyou/monthly/month.rb +0 -122
  78. data/lib/zakuro/version/senmyou/summary/annual_range.rb +0 -186
  79. data/lib/zakuro/version/senmyou/summary/full_range.rb +0 -216
  80. data/lib/zakuro/version/senmyou/summary/specifier.rb +0 -100
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nodoc:
4
+ module Zakuro
5
+ # :nodoc:
6
+ module Calculation
7
+ # :nodoc:
8
+ module Monthly
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
88
+ end
@@ -0,0 +1,201 @@
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 Calculation
10
+ # :nodoc:
11
+ module Monthly
12
+ # :reek:TooManyInstanceVariables { max_instance_variables: 5 }
13
+
14
+ #
15
+ # OperatedMonth 月情報(運用)
16
+ #
17
+ class OperatedMonth < Month
18
+ # @return [Operation::MonthHistory] 変更履歴(月)
19
+ attr_reader :history
20
+ # @return [OperatedSolarTerms] 運用時二十四節気
21
+ attr_reader :operated_solar_terms
22
+
23
+ #
24
+ # 初期化
25
+ #
26
+ # @param [OperatedSolarTerms] operated_solar_terms 運用時二十四節気
27
+ # @param [MonthLabel] month_label 月表示名
28
+ # @param [FirstDay] first_day 月初日(朔日)
29
+ # @param [Array<SolarTerm>] solar_terms 二十四節気
30
+ # @param [Operation::MonthHistory] history 変更履歴(月)
31
+ #
32
+ def initialize(operated_solar_terms:, month_label: MonthLabel.new, first_day: FirstDay.new,
33
+ solar_terms: [], history: Operation::MonthHistory.new)
34
+ super(month_label: month_label, first_day: first_day, solar_terms: solar_terms)
35
+ @history = history
36
+ @operated_solar_terms = operated_solar_terms
37
+ end
38
+
39
+ #
40
+ # 書き換える
41
+ #
42
+ def rewrite
43
+ rewrite_month
44
+ rewrite_solar_terms
45
+ rewrite_first_day
46
+ end
47
+
48
+ #
49
+ # 月ごとの差分で書き換える
50
+ #
51
+ def rewrite_month
52
+ diff = history.diffs.month
53
+
54
+ @month_label = MonthLabel.new(
55
+ number: OperatedMonth.rewrite_month_fields(
56
+ month_diff: diff, month_label: month_label, name: 'number'
57
+ ),
58
+ is_many_days: OperatedMonth.rewrite_month_fields(
59
+ month_diff: diff, month_label: month_label, name: 'is_many_days'
60
+ ),
61
+ leaped: OperatedMonth.rewrite_month_fields(
62
+ month_diff: diff, month_label: month_label, name: 'leaped'
63
+ )
64
+ )
65
+ end
66
+
67
+ def self.rewrite_month_fields(month_diff:, month_label:, name:)
68
+ method_name = name.intern
69
+
70
+ diff = month_diff.send(method_name)
71
+ default = month_label.send(method_name)
72
+ return default if diff.invalid?
73
+
74
+ diff.actual
75
+ end
76
+
77
+ #
78
+ # 二十四節気ごとの差分で書き換える
79
+ #
80
+ def rewrite_solar_terms
81
+ matched, operated_solar_term = @operated_solar_terms.get(
82
+ western_date: first_day.western_date
83
+ )
84
+
85
+ return unless matched
86
+
87
+ @solar_terms = OperatedMonth.create_operated_solar_terms(
88
+ operated_solar_term: operated_solar_term,
89
+ solar_terms: solar_terms
90
+ )
91
+ end
92
+
93
+ #
94
+ # <Description>
95
+ #
96
+ # @param [<Type>] operated_solar_term <description>
97
+ # @param [Array<SolarTerm>] solar_terms 二十四節気
98
+ #
99
+ # @return [Array<SolarTerm>] 二十四節気
100
+ #
101
+ def self.create_operated_solar_terms(operated_solar_term:, solar_terms:)
102
+ index = operated_solar_term.index
103
+
104
+ # 別の月に移動する二十四節気。割り当てない。
105
+ result = remove_solar_term(index: index, solar_terms: solar_terms)
106
+
107
+ return result if used_solar_term?(index: index, solar_terms: solar_terms)
108
+
109
+ result.push(operated_solar_term)
110
+
111
+ result
112
+ end
113
+
114
+ # :reek:ControlParameter
115
+
116
+ #
117
+ # 二十四節気が使用されているか
118
+ #
119
+ # @param [Integer] index 二十四節気番号
120
+ # @param [Array<SolarTerm>] solar_terms 二十四節気
121
+ #
122
+ # @return [True] 使用
123
+ # @return [False] 未使用
124
+ #
125
+ def self.used_solar_term?(index:, solar_terms:)
126
+ solar_terms.each do |solar_term|
127
+ return true if index == solar_term.index
128
+ end
129
+
130
+ false
131
+ end
132
+
133
+ # :reek:ControlParameter
134
+
135
+ #
136
+ # 対象の二十四節気を除外する
137
+ #
138
+ # @param [Integer] index 二十四節気番号
139
+ # @param [Array<SolarTerm>] solar_terms 二十四節気
140
+ #
141
+ # @return [Array<SolarTerm>] 二十四節気(対象除外済)
142
+ #
143
+ def self.remove_solar_term(index:, solar_terms:)
144
+ result = []
145
+ solar_terms.each do |solar_term|
146
+ next if index == solar_term.index
147
+
148
+ result.push(solar_term)
149
+ end
150
+
151
+ result
152
+ end
153
+
154
+ #
155
+ # 月初日ごとの差分で書き換える
156
+ #
157
+ def rewrite_first_day
158
+ diffs = @history.diffs
159
+ return if diffs.invalid_days?
160
+
161
+ days = diffs.days
162
+
163
+ @first_day = FirstDay.new(
164
+ western_date: rewrite_western_date(days: days),
165
+ remainder: rewrite_remainder(days: days)
166
+ )
167
+ end
168
+
169
+ #
170
+ # 月初日の大余小余を日差分で書き換える
171
+ #
172
+ # @param [Integer] days 日差分
173
+ #
174
+ # @return [Remainder] 月初日の大余小余
175
+ #
176
+ def rewrite_remainder(days:)
177
+ remainder = first_day.remainder.clone
178
+ remainder.add!(
179
+ Cycle::AbstractRemainder.new(day: days, minute: 0, second: 0)
180
+ )
181
+
182
+ remainder
183
+ end
184
+
185
+ #
186
+ # 月初日の西暦日を日差分で書き換える
187
+ #
188
+ # @param [Integer] days 日差分
189
+ #
190
+ # @return [Western::Calendar] 月初日の西暦日
191
+ #
192
+ def rewrite_western_date(days:)
193
+ western_date = first_day.western_date.clone
194
+ western_date += days
195
+
196
+ western_date
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../era/western'
4
+ require_relative '../../output/logger'
5
+
6
+ require_relative '../base/multi_gengou_roller'
7
+ require_relative '../base/year'
8
+
9
+ require_relative './transfer/year_boundary'
10
+ require_relative './transfer/western_date_allocation'
11
+
12
+ # :nodoc:
13
+ module Zakuro
14
+ # :nodoc:
15
+ module Calculation
16
+ # :nodoc:
17
+ module Range
18
+ # :reek:TooManyInstanceVariables { max_instance_variables: 6 }
19
+
20
+ #
21
+ # FullRange 完全範囲
22
+ # ある日からある日の範囲を計算可能な年月範囲
23
+ # * 前提として元号年はその元号の開始年から数える
24
+ # * ある日の元号年を求める場合、その元号が含まれる最初の年まで遡る
25
+ # * 元号は一つとは限らない。南北朝などで二つある場合は、古い方の元号から求める
26
+ #
27
+ # NOTE: 割り当てた元号は年初を基準にした元号年である
28
+ # * 元旦を基準にした時の正しい元号を設定している
29
+ # * 引き当てたい日付が元旦ではない場合、その月日に従い元号を再度求める
30
+ # * この再計算が必要になるのは、元号が切り替わる年のみである
31
+ #
32
+ class FullRange
33
+ # @return [Western::Calendar] 開始日
34
+ attr_reader :start_date
35
+ # @return [Western::Calendar] 終了日
36
+ attr_reader :end_date
37
+ # @return [MultiGengouRoller] 改元処理
38
+ attr_reader :multi_gengou_roller
39
+ # @return [Western::Calendar] 最過去の元旦
40
+ attr_reader :new_year_date
41
+ # @return [Integer] 西暦年
42
+ attr_reader :western_year
43
+ # @return [Context] 暦コンテキスト
44
+ attr_reader :context
45
+
46
+ # @return [Output::Logger] ロガー
47
+ LOGGER = Output::Logger.new(location: 'full_range')
48
+
49
+ #
50
+ # 初期化
51
+ #
52
+ # @param [Context] context 暦コンテキスト
53
+ # @param [Western::Calendar] start_date 開始日
54
+ # @param [Western::Calendar] end_date 終了日
55
+ #
56
+ def initialize(context:, start_date: Western::Calendar.new, end_date: Western::Calendar.new)
57
+ @start_date = start_date
58
+ @end_date = end_date
59
+ return if invalid?
60
+
61
+ @context = context
62
+ @multi_gengou_roller = Base::MultiGengouRoller.new(
63
+ start_date: start_date, end_date: end_date
64
+ )
65
+ @new_year_date = @multi_gengou_roller.oldest_date.clone
66
+ @western_year = @new_year_date.year
67
+ end
68
+
69
+ #
70
+ # 無効か
71
+ #
72
+ # @return [True] 無効
73
+ # @return [False] 有効
74
+ #
75
+ def invalid?
76
+ @start_date.invalid?
77
+ end
78
+
79
+ #
80
+ # 完全範囲を取得する
81
+ #
82
+ # @return [Array<Year>] 完全範囲
83
+ #
84
+ def get
85
+ return [] if invalid?
86
+
87
+ years = Transfer::YearBoundary.get(
88
+ annual_ranges: annual_ranges
89
+ )
90
+ years = update_gengou(years: years)
91
+
92
+ Transfer::WesternDateAllocation.update_first_day(
93
+ years: years
94
+ )
95
+
96
+ years
97
+ end
98
+
99
+ # :reek:TooManyStatements { max_statements: 7 }
100
+
101
+ #
102
+ # 完全範囲内の年データを取得する
103
+ #
104
+ # @return [Array<Year>] 年データ(冬至基準)
105
+ #
106
+ def annual_ranges
107
+ oldest_date = @new_year_date
108
+ newest_date = @multi_gengou_roller.newest_date
109
+ annual_range = context.resolver.annual_range
110
+
111
+ years = []
112
+ ((oldest_date.year)..(newest_date.year + 2)).each do |year|
113
+ years.push(
114
+ annual_range.collect_annual_range_after_last_november_1st(
115
+ western_year: year
116
+ )
117
+ )
118
+ end
119
+
120
+ years
121
+ end
122
+
123
+ # :reek:TooManyStatements { max_statements: 8 }
124
+
125
+ #
126
+ # 完全範囲内の年データの元号を開始年基準で更新する
127
+ #
128
+ # @param [Array<Year>] years 年データ(元旦基準)
129
+ #
130
+ # @return [Array<Year>] 元号更新済み年データ(元旦基準)
131
+ #
132
+ def update_gengou(years:)
133
+ updated_years = []
134
+
135
+ nearest_end_date = choise_nearest_end_date
136
+
137
+ years.each do |year|
138
+ next_year(years: updated_years, year: year)
139
+
140
+ if @new_year_date > nearest_end_date
141
+ @multi_gengou_roller.transfer
142
+ nearest_end_date = choise_nearest_end_date
143
+ end
144
+ @multi_gengou_roller.next_year
145
+ end
146
+
147
+ updated_years
148
+ end
149
+
150
+ private
151
+
152
+ #
153
+ # 元号処理対象の年を進める
154
+ #
155
+ # @param [Array<Year>] years 元号処理済み年データ(元旦基準)
156
+ # @param [Year] year 元号処理前の年(元旦基準)
157
+ #
158
+ def next_year(years:, year:)
159
+ updated_year = update_year(year: year)
160
+
161
+ years.push(updated_year)
162
+
163
+ next_new_year_date(total_days: updated_year.total_days)
164
+
165
+ nil
166
+ end
167
+
168
+ #
169
+ # 年の元号を更新する
170
+ #
171
+ # @param [Year] year 元号処理前の年(元旦基準)
172
+ #
173
+ # @return [Year] 元号処理済の年(元旦基準)
174
+ #
175
+ def update_year(year:)
176
+ multi_gengou = @multi_gengou_roller.multi_gengou.clone
177
+
178
+ updated_year = Base::Year.new(
179
+ multi_gengou: multi_gengou, new_year_date: @new_year_date.clone,
180
+ months: year.months
181
+ )
182
+ updated_year.commit
183
+
184
+ updated_year
185
+ end
186
+
187
+ #
188
+ # 次の年に進める
189
+ #
190
+ # @param [Integer] total_days 年の日数
191
+ #
192
+ def next_new_year_date(total_days:)
193
+ @new_year_date += total_days
194
+ @multi_gengou_roller.next(days: total_days)
195
+
196
+ nil
197
+ end
198
+
199
+ #
200
+ # 現在日からみて直近の未来に対する元号の切替前日を求める
201
+ #
202
+ # @return [Western::Calendar] 元号の切替前日
203
+ #
204
+ def choise_nearest_end_date
205
+ @multi_gengou_roller.choise_nearest_end_date
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end