zakuro 0.0.1 → 0.1.2

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 (74) 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 +126 -33
  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/operation/month/parser.rb +373 -0
  26. data/lib/zakuro/operation/month/type.rb +453 -0
  27. data/lib/zakuro/operation/month/validator.rb +802 -0
  28. data/lib/zakuro/operation/operation.rb +66 -0
  29. data/lib/zakuro/operation/yaml/month.yaml +6452 -0
  30. data/lib/zakuro/output/error.rb +2 -0
  31. data/lib/zakuro/output/logger.rb +2 -0
  32. data/lib/zakuro/output/response.rb +21 -19
  33. data/lib/zakuro/result/core.rb +52 -0
  34. data/lib/zakuro/result/data.rb +187 -0
  35. data/lib/zakuro/result/operation.rb +114 -0
  36. data/lib/zakuro/result/result.rb +37 -0
  37. data/lib/zakuro/{output → tools}/stringifier.rb +16 -9
  38. data/lib/zakuro/tools/typeof.rb +33 -0
  39. data/lib/zakuro/version.rb +1 -1
  40. data/lib/zakuro/version/senmyou/README.md +3 -1
  41. data/lib/zakuro/version/senmyou/base/era.rb +3 -1
  42. data/lib/zakuro/version/senmyou/base/multi_gengou.rb +98 -0
  43. data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +217 -0
  44. data/lib/zakuro/version/senmyou/base/remainder.rb +4 -4
  45. data/lib/zakuro/version/senmyou/base/solar_term.rb +82 -0
  46. data/lib/zakuro/version/senmyou/base/year.rb +52 -6
  47. data/lib/zakuro/version/senmyou/monthly/first_day.rb +44 -0
  48. data/lib/zakuro/version/senmyou/monthly/initialized_month.rb +119 -0
  49. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +3 -3
  50. data/lib/zakuro/version/senmyou/monthly/month.rb +136 -67
  51. data/lib/zakuro/version/senmyou/monthly/month_label.rb +87 -0
  52. data/lib/zakuro/version/senmyou/monthly/operated_month.rb +196 -0
  53. data/lib/zakuro/version/senmyou/{summary/annual_data.rb → range/annual_range.rb} +34 -61
  54. data/lib/zakuro/version/senmyou/range/full_range.rb +194 -0
  55. data/lib/zakuro/version/senmyou/range/operated_range.rb +126 -0
  56. data/lib/zakuro/version/senmyou/range/operated_solar_terms.rb +181 -0
  57. data/lib/zakuro/version/senmyou/range/western_date_allocation.rb +68 -0
  58. data/lib/zakuro/version/senmyou/range/year_boundary.rb +138 -0
  59. data/lib/zakuro/version/senmyou/senmyou.rb +2 -2
  60. data/lib/zakuro/version/senmyou/specifier/single_day_specifier.rb +102 -0
  61. data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +2 -2
  62. data/lib/zakuro/version/senmyou/stella/solar_average.rb +105 -128
  63. data/lib/zakuro/version/senmyou/stella/solar_location.rb +213 -0
  64. data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +4 -189
  65. data/lib/zakuro/version/senmyou/summary/single.rb +125 -0
  66. data/lib/zakuro/version_factory.rb +1 -1
  67. metadata +46 -15
  68. data/lib/zakuro/era/gengou/set-001-until-south.yaml +0 -375
  69. data/lib/zakuro/era/gengou/set-002-from-north.yaml +0 -166
  70. data/lib/zakuro/era/gengou/set-003-modern.yaml +0 -12
  71. data/lib/zakuro/era/japan.rb +0 -630
  72. data/lib/zakuro/output/result.rb +0 -219
  73. data/lib/zakuro/version/senmyou/base/gengou.rb +0 -210
  74. data/lib/zakuro/version/senmyou/summary/gengou_data.rb +0 -294
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './full_range'
4
+ require_relative './operated_solar_terms'
5
+ require_relative '../../../operation/operation'
6
+ require_relative '../monthly/operated_month'
7
+
8
+ # :nodoc:
9
+ module Zakuro
10
+ # :nodoc:
11
+ module Senmyou
12
+ #
13
+ # OperatedRange 運用結果範囲
14
+ #
15
+ # 何らかの理由により、計算された暦とは異なる運用結果である場合、その結果に合わせて計算結果を上書きする
16
+ class OperatedRange
17
+ # @return [Array<Year>] 年データ(完全範囲)
18
+ attr_reader :years
19
+ # @return [OperatedSolarTerms] 運用時二十四節気
20
+ attr_reader :operated_solar_terms
21
+
22
+ #
23
+ # 初期化
24
+ #
25
+ # @param [Array<Year>] years 年データ(完全範囲)
26
+ #
27
+ def initialize(years: [])
28
+ @years = years
29
+ @operated_solar_terms = OperatedSolarTerms.new(years: @years)
30
+ @operated_solar_terms.create
31
+ end
32
+
33
+ #
34
+ # 運用結果範囲を取得する
35
+ #
36
+ # @return [Array<Year>] 運用結果範囲
37
+ #
38
+ def get
39
+ rewrite
40
+ end
41
+
42
+ #
43
+ # 運用結果に書き換える
44
+ #
45
+ # @return [Array<Year>] 運用結果範囲
46
+ #
47
+ def rewrite
48
+ operated_years = []
49
+
50
+ years.each do |year|
51
+ operated_year = OperatedRange.rewrite_year(
52
+ year: year, operated_solar_terms: @operated_solar_terms
53
+ )
54
+ operated_years.push(operated_year)
55
+ end
56
+
57
+ operated_years
58
+ end
59
+
60
+ #
61
+ # 年を書き換える
62
+ #
63
+ # @param [Year] year 年
64
+ # @param [OperatedSolarTerms] operated_solar_terms 運用時二十四節気
65
+ #
66
+ # @return [Year] 年
67
+ #
68
+ def self.rewrite_year(year:, operated_solar_terms:)
69
+ result = Year.new(multi_gengou: year.multi_gengou, new_year_date: year.new_year_date)
70
+ year.months.each do |month|
71
+ result.push(month: resolve_month(
72
+ month: month, operated_solar_terms: operated_solar_terms
73
+ ))
74
+ end
75
+
76
+ result.commit
77
+
78
+ result
79
+ end
80
+
81
+ #
82
+ # 履歴情報の有無に応じた月にする
83
+ #
84
+ # @param [Month] month 月
85
+ # @param [OperatedSolarTerms] operated_solar_terms 運用時二十四節気
86
+ #
87
+ # @return [Month] 月
88
+ #
89
+ def self.resolve_month(month:, operated_solar_terms:)
90
+ history = Operation.specify_history(western_date: month.western_date)
91
+
92
+ return month if history.invalid?
93
+
94
+ OperatedRange.rewrite_month(
95
+ month: month, history: history, operated_solar_terms: operated_solar_terms
96
+ )
97
+ end
98
+
99
+ #
100
+ # 月を運用結果に書き換える
101
+ #
102
+ # @param [Month] month 月
103
+ # @param [Operation::MonthHistory] history 変更履歴
104
+ # @param [OperatedSolarTerms] operated_solar_terms 運用時二十四節気
105
+ #
106
+ # @return [Month] 月(運用結果)
107
+ #
108
+ def self.rewrite_month(month:, history:, operated_solar_terms:)
109
+ return month unless month.western_date == history.western_date
110
+
111
+ operated_month = OperatedMonth.new(
112
+ month_label: month.month_label, first_day: month.first_day,
113
+ solar_terms: month.solar_terms, history: history,
114
+ operated_solar_terms: operated_solar_terms
115
+ )
116
+
117
+ operated_month.rewrite
118
+
119
+ Month.new(
120
+ month_label: operated_month.month_label, first_day: operated_month.first_day,
121
+ solar_terms: operated_month.solar_terms
122
+ )
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './full_range'
4
+ require_relative '../../../operation/operation'
5
+ require_relative '../monthly/month'
6
+
7
+ # TODO: solar_termの中はsrc/destだが、yamlはcalc/actual。統一したい。
8
+
9
+ # :nodoc:
10
+ module Zakuro
11
+ # :nodoc:
12
+ module Senmyou
13
+ #
14
+ # OperatedSolarTerm 運用時二十四節気
15
+ #
16
+ class OperatedSolarTerms
17
+ # @return [Array<Year>] 完全範囲(年データ)
18
+ attr_reader :years
19
+ # @return [Hash<String, SolarTerm>] 二十四節気の移動元/移動先(西暦日 -> 対応する二十四節気)
20
+ #
21
+ # * 移動元の二十四節気:無効な大余小余あり(削除対象)
22
+ # * 移動先の二十四節気:移動元からの二十四節気(追加対象)
23
+ #
24
+ attr_reader :directions
25
+
26
+ #
27
+ # 初期化
28
+ #
29
+ # @param [Array<Year>] years 完全範囲(年データ)
30
+ #
31
+ def initialize(years: [])
32
+ @years = years
33
+ @directions = {}
34
+ end
35
+
36
+ #
37
+ # データ生成する
38
+ #
39
+ # @return [<Type>] <description>
40
+ #
41
+ def create
42
+ @directions = create_directions
43
+ end
44
+
45
+ #
46
+ # 二十四節気を取得する
47
+ #
48
+ # @param [Western::Calendar] western_date 月初日の西暦日
49
+ #
50
+ # @return [True] 対象あり
51
+ # @return [False] 対象なし
52
+ # @return [SolarTerm] 二十四節気
53
+ #
54
+ def get(western_date: Western::Calendar.new)
55
+ solar_term = @directions.fetch(western_date.format, SolarTerm.new)
56
+
57
+ # 合致しない場合
58
+ return false, SolarTerm.new if solar_term.empty?
59
+
60
+ # 合致した上で、二十四節気が移動元(削除対象)の場合
61
+ # 合致した上で、二十四節気が移動先(追加対象)の場合
62
+ [true, solar_term]
63
+ end
64
+
65
+ #
66
+ # 二十四節気の移動元/移動先を生成する
67
+ #
68
+ # @return [Hash<String, SolarTerm>] 二十四節気の移動元/移動先(西暦日 -> 対応する二十四節気)
69
+ #
70
+ def create_directions
71
+ directions = {}
72
+
73
+ years.each do |year|
74
+ OperatedSolarTerms.create_directions_with_months(
75
+ directions: directions, months: year.months
76
+ )
77
+ end
78
+
79
+ directions
80
+ end
81
+
82
+ # :reek:TooManyStatements { max_statements: 6 }
83
+
84
+ #
85
+ # 年内の全ての月の移動方向を作成する
86
+ #
87
+ # @param [Hash<String, SolarTerm>] directions 二十四節気の移動元/移動先(西暦日 -> 対応する二十四節気)
88
+ # @param [Array<Month>] months 年内の全ての月
89
+ #
90
+ def self.create_directions_with_months(directions: {}, months: [])
91
+ months.each do |month|
92
+ history = Operation.specify_history(western_date: month.western_date)
93
+
94
+ next if history.invalid?
95
+
96
+ direction = history.diffs.solar_term
97
+
98
+ next if direction.invalid?
99
+
100
+ OperatedSolarTerms.create_directions_each_month(
101
+ directions: directions, direction: direction, month: month
102
+ )
103
+ end
104
+ end
105
+
106
+ #
107
+ # 月毎の移動方向を作成する
108
+ #
109
+ # @param [Hash<String, SolarTerm>] directions 二十四節気の移動元/移動先(西暦日 -> 対応する二十四節気)
110
+ # @param [Operation::SolarTerm::Diretion] 二十四節気(移動)
111
+ # @param [Month] 月
112
+ #
113
+ def self.create_directions_each_month(directions: {},
114
+ direction: Operation::SolarTerm::Diretion.new,
115
+ month: Month.new)
116
+
117
+ month.solar_terms.each do |solar_term|
118
+ OperatedSolarTerms.push_source(directions: directions, direction: direction,
119
+ solar_term: solar_term)
120
+ end
121
+ OperatedSolarTerms.push_destination(directions: directions,
122
+ destination: direction.destination)
123
+ end
124
+
125
+ #
126
+ # 移動先に有効な二十四節気(差し替える二十四節気)を指定する
127
+ #
128
+ # @param [Hash<String, SolarTerm>] directions 二十四節気の移動元/移動先(西暦日 -> 対応する二十四節気)
129
+ # @param [Operation::SolarTerm::Direction] source 二十四節気(移動)
130
+ # @param [SolarTerm] solar_term 二十四節気(計算値)
131
+ #
132
+ def self.push_source(directions: {}, direction: Operation::SolarTerm::Direction.new,
133
+ solar_term: SolarTerm.new)
134
+ source = direction.source
135
+
136
+ return if source.invalid?
137
+
138
+ return unless source.index == solar_term.index
139
+
140
+ # 移動先に移動元の二十四節気を指定する
141
+ directions[source.to.format] = OperatedSolarTerms.created_source(
142
+ direction: direction, solar_term: solar_term
143
+ )
144
+ end
145
+
146
+ #
147
+ # 移動先に有効な二十四節気(差し替える二十四節気)を生成する
148
+ #
149
+ # @param [Operation::SolarTerm::Direction] source 二十四節気(移動)
150
+ # @param [SolarTerm] solar_term 二十四節気(計算値)
151
+ #
152
+ # @return [SolarTerm] 二十四節気(運用値)
153
+ #
154
+ def self.created_source(direction: Operation::SolarTerm::Direction.new,
155
+ solar_term: SolarTerm.new)
156
+ operated_solar_term = solar_term.clone
157
+
158
+ unless direction.invalid_days?
159
+ # 二十四節気の大余をずらす
160
+ operated_solar_term.remainder.add!(
161
+ Remainder.new(day: direction.days, minute: 0, second: 0)
162
+ )
163
+ end
164
+
165
+ operated_solar_term
166
+ end
167
+
168
+ #
169
+ # 移動元に無効な二十四節気(連番のみ指定)を指定する
170
+ #
171
+ # @param [Hash<String, SolarTerm>] directions 二十四節気の移動元/移動先(西暦日 -> 対応する二十四節気)
172
+ # @param [Operation::SolarTerm::Destination] destination 二十四節気(移動先)
173
+ #
174
+ def self.push_destination(directions: {}, destination: Operation::SolarTerm::Destination.new)
175
+ return if destination.invalid?
176
+
177
+ directions[destination.from.format] = SolarTerm.new(index: destination.index)
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nodoc:
4
+ module Zakuro
5
+ # :nodoc:
6
+ module Senmyou
7
+ #
8
+ # WesternDateAllocation 西暦日の割り当て
9
+ #
10
+ module WesternDateAllocation
11
+ #
12
+ # 月初日の西暦日を更新する
13
+ #
14
+ # @param [Array<Year>] years 完全範囲(月初日なし)
15
+ #
16
+ # @return [Array<Year>] 完全範囲(月初日あり)
17
+ #
18
+ def self.get(years:)
19
+ update_first_day(years: years)
20
+
21
+ years
22
+ end
23
+
24
+ #
25
+ # 月初日の西暦日を更新する
26
+ #
27
+ # @param [Array<Year>] years 完全範囲(月初日なし)
28
+ #
29
+ def self.update_first_day(years:)
30
+ years.each_with_index do |year, index|
31
+ new_year_date = year.new_year_date.clone
32
+
33
+ months = year.months
34
+ update_first_day_within_all_months(
35
+ new_year_date: new_year_date, months: months
36
+ )
37
+
38
+ years[index] = Year.new(
39
+ multi_gengou: year.multi_gengou, new_year_date: new_year_date,
40
+ months: months, total_days: year.total_days
41
+ )
42
+ end
43
+ end
44
+
45
+ #
46
+ # 全ての月で月初日の西暦日を更新する
47
+ #
48
+ # @param [Western::Calendar] new_year_date 元旦
49
+ # @param [Array<Month>] months 月データ
50
+ #
51
+ def self.update_first_day_within_all_months(new_year_date:, months:)
52
+ date = new_year_date.clone
53
+ months.each_with_index do |month, index|
54
+ updated_month = Month.new(
55
+ month_label: month.month_label,
56
+ first_day: FirstDay.new(remainder: month.first_day.remainder,
57
+ western_date: date),
58
+ solar_terms: month.solar_terms
59
+ )
60
+ months[index] = updated_month
61
+
62
+ date = date.clone + updated_month.days
63
+ end
64
+ end
65
+ private_class_method :update_first_day_within_all_months
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base/multi_gengou_roller'
4
+
5
+ require_relative '../../../era/western'
6
+ require_relative './annual_range'
7
+
8
+ require_relative '../base/year'
9
+
10
+ # :nodoc:
11
+ module Zakuro
12
+ # :nodoc:
13
+ module Senmyou
14
+ #
15
+ # YearBoundary 年境界
16
+ #
17
+ module YearBoundary
18
+ #
19
+ # 年間範囲内の年データの開始月を変更する
20
+ #
21
+ # @param [Array<Year>] annual_ranges 年データ(冬至基準)
22
+ #
23
+ # @return [Array<Year>] 年データ(元旦基準)
24
+ #
25
+ def self.get(annual_ranges:)
26
+ categorize(annual_ranges: annual_ranges)
27
+ rearranged_years(annual_ranges: annual_ranges)
28
+ end
29
+
30
+ #
31
+ # 年間範囲内の年データの開始月を変更する
32
+ #
33
+ # @param [Array<Year>] annual_ranges 年データ(冬至基準)
34
+ #
35
+ # @return [Array<Year>] 年データ(元旦基準)
36
+ #
37
+ def self.rearranged_years(annual_ranges:)
38
+ years = []
39
+
40
+ (0..(annual_ranges.size - 2)).each do |index|
41
+ year = rearranged_year(annual_ranges: annual_ranges, index: index)
42
+ years.push(year)
43
+ end
44
+
45
+ years
46
+ end
47
+ private_class_method :rearranged_years
48
+
49
+ #
50
+ # 年間範囲を昨年/今年で分類する
51
+ #
52
+ # @param [Array<Year>] annual_range 1年データ
53
+ #
54
+ def self.categorize(annual_ranges:)
55
+ annual_ranges.each do |annual_range|
56
+ categorize_year(annual_range: annual_range)
57
+ end
58
+ end
59
+ private_class_method :categorize
60
+
61
+ #
62
+ # 各月を昨年/今年で分類する
63
+ #
64
+ # @param [Array<Month>] annual_range 1年データ
65
+ #
66
+ def self.categorize_year(annual_range:)
67
+ is_last_year = true
68
+ annual_range.each_with_index do |month, index|
69
+ is_last_year = false if month.number == 1
70
+
71
+ annual_range[index] = InitializedMonth.new(
72
+ month_label: month.month_label, first_day: month.first_day,
73
+ solar_terms: month.solar_terms, phase_index: month.phase_index,
74
+ is_last_year: is_last_year
75
+ )
76
+ end
77
+ end
78
+ private_class_method :categorize_year
79
+
80
+ #
81
+ # 年データの開始月を変更する
82
+ #
83
+ # @param [Array<Year>] annual_ranges 年データ(冬至基準)
84
+ # @param [Integer] index 対象年の要素番号
85
+ #
86
+ # @return [Year] 年データ(元旦基準)
87
+ #
88
+ def self.rearranged_year(annual_ranges:, index:)
89
+ current_annual_range = annual_ranges[index]
90
+ next_annual_range = annual_ranges[index + 1]
91
+
92
+ year = push_current_year(annual_range: current_annual_range)
93
+ push_last_year(annual_range: next_annual_range, year: year)
94
+
95
+ year
96
+ end
97
+ private_class_method :rearranged_year
98
+
99
+ #
100
+ # 当年データを生成する
101
+ #
102
+ # @param [Array<Year>] annual_ranges 年データ(冬至基準)
103
+ # @param [Year] year 対象年
104
+ #
105
+ # @return [Year] 当年月ありの対象年
106
+ #
107
+ def self.push_current_year(annual_range:, year: Year.new)
108
+ annual_range.each do |month|
109
+ next if month.is_last_year
110
+
111
+ year.push(month: month)
112
+ end
113
+
114
+ year
115
+ end
116
+ private_class_method :push_current_year
117
+
118
+ #
119
+ # 昨年データを生成する
120
+ #
121
+ # @param [Array<Year>] annual_ranges 年データ(冬至基準)
122
+ # @param [Year] year 対象年
123
+ #
124
+ # @return [Year] 昨年月ありの対象年
125
+ #
126
+ def self.push_last_year(annual_range:, year: Year.new)
127
+ annual_range.each do |month|
128
+ next unless month.is_last_year
129
+
130
+ year.push(month: month)
131
+ end
132
+
133
+ year
134
+ end
135
+ private_class_method :push_last_year
136
+ end
137
+ end
138
+ end