zakuro 0.0.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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