zakuro 0.0.3 → 0.1.0
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.
- checksums.yaml +4 -4
- data/README.md +85 -43
- data/doc/operation.md +25 -0
- data/doc/operation/csv/month.csv +202 -0
- data/doc/operation/operation.xlsx +0 -0
- data/doc/operation/transfer.rb +73 -0
- data/lib/zakuro/era/japan/gengou.rb +106 -0
- data/lib/zakuro/era/japan/gengou/parser.rb +169 -0
- data/lib/zakuro/era/japan/gengou/type.rb +178 -0
- data/lib/zakuro/era/japan/gengou/validator.rb +234 -0
- data/lib/zakuro/era/japan/reki.rb +91 -0
- data/lib/zakuro/era/{gengou → japan/yaml}/set-001-until-south.yaml +0 -0
- data/lib/zakuro/era/{gengou → japan/yaml}/set-002-from-north.yaml +0 -0
- data/lib/zakuro/era/{gengou → japan/yaml}/set-003-modern.yaml +0 -0
- data/lib/zakuro/era/western.rb +1 -1
- data/lib/zakuro/operation/month/parser.rb +277 -0
- data/lib/zakuro/operation/month/type.rb +452 -0
- data/lib/zakuro/operation/month/validator.rb +498 -0
- data/lib/zakuro/operation/operation.rb +45 -0
- data/lib/zakuro/operation/yaml/month.yaml +6452 -0
- data/lib/zakuro/output/error.rb +2 -0
- data/lib/zakuro/output/logger.rb +2 -0
- data/lib/zakuro/output/response.rb +17 -15
- data/lib/zakuro/result/core.rb +52 -0
- data/lib/zakuro/result/data.rb +187 -0
- data/lib/zakuro/result/operation.rb +86 -0
- data/lib/zakuro/result/result.rb +37 -0
- data/lib/zakuro/{output → tools}/stringifier.rb +14 -7
- data/lib/zakuro/tools/typeof.rb +33 -0
- data/lib/zakuro/version.rb +1 -1
- data/lib/zakuro/version/senmyou/base/era.rb +1 -1
- data/lib/zakuro/version/senmyou/base/multi_gengou.rb +1 -1
- data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +13 -1
- data/lib/zakuro/version/senmyou/base/solar_term.rb +10 -0
- data/lib/zakuro/version/senmyou/monthly/first_day.rb +44 -0
- data/lib/zakuro/version/senmyou/monthly/initialized_month.rb +48 -0
- data/lib/zakuro/version/senmyou/monthly/month.rb +127 -68
- data/lib/zakuro/version/senmyou/monthly/month_label.rb +87 -0
- data/lib/zakuro/version/senmyou/monthly/operated_month.rb +167 -0
- data/lib/zakuro/version/senmyou/{summary → range}/annual_range.rb +20 -23
- data/lib/zakuro/version/senmyou/{summary → range}/full_range.rb +102 -2
- data/lib/zakuro/version/senmyou/range/operated_range.rb +105 -0
- data/lib/zakuro/version/senmyou/range/operated_solar_terms.rb +163 -0
- data/lib/zakuro/version/senmyou/senmyou.rb +2 -2
- data/lib/zakuro/version/senmyou/{summary/specifier.rb → specifier/single_day_specifier.rb} +13 -14
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +3 -7
- data/lib/zakuro/version/senmyou/summary/single.rb +71 -0
- data/lib/zakuro/version_factory.rb +1 -1
- metadata +35 -11
- data/lib/zakuro/era/japan.rb +0 -664
- data/lib/zakuro/output/result.rb +0 -225
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# TODO: moduleでMonthly とする(全暦むけに共通化したあと)
|
4
|
+
|
5
|
+
# :nodoc:
|
6
|
+
module Zakuro
|
7
|
+
# :nodoc:
|
8
|
+
module Senmyou
|
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
|
@@ -0,0 +1,167 @@
|
|
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 Senmyou
|
10
|
+
#
|
11
|
+
# OperatedMonth 月情報(運用)
|
12
|
+
#
|
13
|
+
class OperatedMonth < Month
|
14
|
+
# @return [Operation::MonthHistory] 変更履歴(月)
|
15
|
+
attr_reader :history
|
16
|
+
# @return [OperatedSolarTerms] 運用時二十四節気
|
17
|
+
attr_reader :operated_solar_terms
|
18
|
+
|
19
|
+
#
|
20
|
+
# 初期化
|
21
|
+
#
|
22
|
+
# @param [MonthLabel] month_label 月表示名
|
23
|
+
# @param [FirstDay] first_day 月初日(朔日)
|
24
|
+
# @param [Array<SolarTerm>] solar_terms 二十四節気
|
25
|
+
# @param [Operation::MonthHistory] history 変更履歴(月)
|
26
|
+
#
|
27
|
+
def initialize(operated_solar_terms:, month_label: MonthLabel.new, first_day: FirstDay.new, solar_terms: [],
|
28
|
+
history: Operation::MonthHistory.new)
|
29
|
+
super(month_label: month_label, first_day: first_day, solar_terms: solar_terms)
|
30
|
+
@history = history
|
31
|
+
@operated_solar_terms = operated_solar_terms
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# 書き換える
|
36
|
+
#
|
37
|
+
def rewrite
|
38
|
+
rewrite_month
|
39
|
+
rewrite_solar_terms
|
40
|
+
rewrite_first_day
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# 月ごとの差分で書き換える
|
45
|
+
#
|
46
|
+
def rewrite_month
|
47
|
+
diff = history.diffs.month
|
48
|
+
|
49
|
+
@month_label = MonthLabel.new(
|
50
|
+
number: rewrite_number(diff: diff.number),
|
51
|
+
is_many_days: rewrite_many_days(diff: diff.days),
|
52
|
+
leaped: rewrite_leaped(diff: diff.leaped)
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# 月ごとの差分(月)で書き換える
|
58
|
+
#
|
59
|
+
# @param [Operation::Number] diff 差分
|
60
|
+
#
|
61
|
+
# @return [Integer] 月
|
62
|
+
#
|
63
|
+
def rewrite_number(diff:)
|
64
|
+
return month_label.number if diff.invalid?
|
65
|
+
|
66
|
+
diff.actual
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# 月ごとの差分(月の大小)で書き換える
|
71
|
+
#
|
72
|
+
# @param [Operation::Days] diff 差分
|
73
|
+
#
|
74
|
+
# @return [Integer] 月の大小
|
75
|
+
#
|
76
|
+
def rewrite_many_days(diff:)
|
77
|
+
return month_label.is_many_days if diff.invalid?
|
78
|
+
|
79
|
+
diff.many_days_actual?
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# 月ごとの差分(閏有無)で書き換える
|
84
|
+
#
|
85
|
+
# @param [Operation::Days] diff 差分
|
86
|
+
#
|
87
|
+
# @return [True] 閏あり
|
88
|
+
# @return [False] 閏なし
|
89
|
+
#
|
90
|
+
def rewrite_leaped(diff:)
|
91
|
+
return month_label.leaped if diff.invalid?
|
92
|
+
|
93
|
+
diff.actual
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# 二十四節気ごとの差分で書き換える
|
98
|
+
#
|
99
|
+
def rewrite_solar_terms
|
100
|
+
# TODO: リファクタリング
|
101
|
+
operated_solar_terms = []
|
102
|
+
matched, operated_solar_term = @operated_solar_terms.get(
|
103
|
+
western_date: @first_day.western_date
|
104
|
+
)
|
105
|
+
|
106
|
+
return unless matched
|
107
|
+
|
108
|
+
used = false
|
109
|
+
@solar_terms.each do |solar_term|
|
110
|
+
if operated_solar_term.index == solar_term.index
|
111
|
+
used = true
|
112
|
+
next
|
113
|
+
end
|
114
|
+
|
115
|
+
operated_solar_terms.push(solar_term)
|
116
|
+
end
|
117
|
+
|
118
|
+
operated_solar_terms.push(operated_solar_term) unless used
|
119
|
+
|
120
|
+
@solar_terms = operated_solar_terms
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# 月初日ごとの差分で書き換える
|
125
|
+
#
|
126
|
+
def rewrite_first_day
|
127
|
+
diffs = @history.diffs
|
128
|
+
return if diffs.invalid_days?
|
129
|
+
|
130
|
+
days = diffs.days
|
131
|
+
|
132
|
+
@first_day = FirstDay.new(
|
133
|
+
western_date: rewrite_western_date(days: days),
|
134
|
+
remainder: rewrite_remainder(days: days)
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# 月初日の大余小余を日差分で書き換える
|
140
|
+
#
|
141
|
+
# @param [Integer] days 日差分
|
142
|
+
#
|
143
|
+
# @return [Remainder] 月初日の大余小余
|
144
|
+
#
|
145
|
+
def rewrite_remainder(days:)
|
146
|
+
remainder = @first_day.remainder.clone
|
147
|
+
remainder.add!(Remainder.new(day: days, minute: 0, second: 0))
|
148
|
+
|
149
|
+
remainder
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# 月初日の西暦日を日差分で書き換える
|
154
|
+
#
|
155
|
+
# @param [Integer] days 日差分
|
156
|
+
#
|
157
|
+
# @return [Western::Calendar] 月初日の西暦日
|
158
|
+
#
|
159
|
+
def rewrite_western_date(days:)
|
160
|
+
western_date = @first_day.western_date.clone
|
161
|
+
western_date += days
|
162
|
+
|
163
|
+
western_date
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative '../../../output/logger'
|
4
4
|
require_relative '../base/remainder'
|
5
|
-
require_relative '../monthly/
|
5
|
+
require_relative '../monthly/initialized_month'
|
6
6
|
require_relative '../base/solar_term'
|
7
7
|
require_relative '../monthly/lunar_phase'
|
8
8
|
require_relative '../stella/solar_orbit'
|
@@ -13,7 +13,9 @@ require_relative '../stella/lunar_orbit'
|
|
13
13
|
module Zakuro
|
14
14
|
# :nodoc:
|
15
15
|
module Senmyou
|
16
|
-
#
|
16
|
+
#
|
17
|
+
# AnnualRange 年間範囲
|
18
|
+
#
|
17
19
|
module AnnualRange
|
18
20
|
# @return [Logger] ロガー
|
19
21
|
LOGGER = Logger.new(location: 'annual_range')
|
@@ -126,8 +128,9 @@ module Zakuro
|
|
126
128
|
adjusted = lunar_phase.next_month
|
127
129
|
|
128
130
|
result.push(
|
129
|
-
|
130
|
-
|
131
|
+
InitializedMonth.new(month_label: MonthLabel.new(number: month),
|
132
|
+
first_day: FirstDay.new(remainder: adjusted),
|
133
|
+
is_last_year: is_last_year, phase_index: 0)
|
131
134
|
)
|
132
135
|
is_last_year = false if month == 12
|
133
136
|
end
|
@@ -141,14 +144,12 @@ module Zakuro
|
|
141
144
|
# @param [Array<Month>] annual_range 1年データ
|
142
145
|
#
|
143
146
|
def self.apply_big_and_small_of_the_month(annual_range:)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
other: next_month.remainder.day
|
151
|
-
)
|
147
|
+
annual_range.each_with_index do |range, index|
|
148
|
+
# 最後は比較対象がないためスキップする(=計算外の余分な月が最後に必要である)
|
149
|
+
next if index == annual_range.size - 1
|
150
|
+
|
151
|
+
next_month = annual_range[index + 1]
|
152
|
+
range.eval_many_days(next_month_day: next_month.remainder.day)
|
152
153
|
end
|
153
154
|
end
|
154
155
|
private_class_method :apply_big_and_small_of_the_month
|
@@ -165,20 +166,16 @@ module Zakuro
|
|
165
166
|
# 閏による月の再調整を行う
|
166
167
|
leaped = false
|
167
168
|
annual_range.each_with_index do |month, index|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
169
|
+
month.eval_leaped
|
170
|
+
# NOTE: 初回閏月(閏11月)は前回月が存在しないため調整外
|
171
|
+
leaped = true if month.leaped? && !index.zero?
|
172
|
+
|
173
173
|
next unless leaped
|
174
174
|
|
175
175
|
# NOTE: 常気法では閏月は2-3年に一度のため、1年に二度発生しない前提
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
number = 12
|
180
|
-
end
|
181
|
-
month.number = number
|
176
|
+
|
177
|
+
# 閏の分だけ1ヶ月ずらす
|
178
|
+
month.back_to_last_month
|
182
179
|
end
|
183
180
|
end
|
184
181
|
private_class_method :adjust_leap_month
|
@@ -5,6 +5,8 @@ require_relative '../base/multi_gengou_roller'
|
|
5
5
|
require_relative '../../../era/western'
|
6
6
|
require_relative './annual_range'
|
7
7
|
|
8
|
+
require_relative '../base/year'
|
9
|
+
|
8
10
|
# :nodoc:
|
9
11
|
module Zakuro
|
10
12
|
# :nodoc:
|
@@ -20,25 +22,82 @@ module Zakuro
|
|
20
22
|
# * 引き当てたい日付が元旦ではない場合、その月日に従い元号を再度求める
|
21
23
|
# * この再計算が必要になるのは、元号が切り替わる年のみである
|
22
24
|
class FullRange
|
23
|
-
|
25
|
+
# @return [Western::Calendar] 開始日
|
26
|
+
attr_reader :start_date
|
27
|
+
# @return [Western::Calendar] 終了日
|
28
|
+
attr_reader :end_date
|
29
|
+
# @return [MultiGengouRoller] 改元処理
|
30
|
+
attr_reader :multi_gengou_roller
|
31
|
+
# @return [Western::Calendar] 最過去の元旦
|
32
|
+
attr_reader :new_year_date
|
33
|
+
# @return [Integer] 西暦年
|
34
|
+
attr_reader :western_year
|
24
35
|
|
25
36
|
# @return [Logger] ロガー
|
26
37
|
LOGGER = Logger.new(location: 'full_range')
|
27
38
|
|
39
|
+
#
|
40
|
+
# 初期化
|
41
|
+
#
|
42
|
+
# @param [Western::Calendar] start_date 開始日
|
43
|
+
# @param [Western::Calendar] end_date 終了日
|
44
|
+
#
|
28
45
|
def initialize(start_date: Western::Calendar.new, end_date: Western::Calendar.new)
|
46
|
+
@start_date = start_date
|
47
|
+
@end_date = end_date
|
48
|
+
return if invalid?
|
49
|
+
|
29
50
|
@multi_gengou_roller = MultiGengouRoller.new(start_date: start_date, end_date: end_date)
|
30
51
|
@new_year_date = @multi_gengou_roller.oldest_date.clone
|
31
52
|
@western_year = @new_year_date.year
|
32
53
|
end
|
33
54
|
|
55
|
+
#
|
56
|
+
# 無効か
|
57
|
+
#
|
58
|
+
# @return [True] 無効
|
59
|
+
# @return [False] 有効
|
60
|
+
#
|
61
|
+
def invalid?
|
62
|
+
@start_date.invalid?
|
63
|
+
end
|
64
|
+
|
34
65
|
#
|
35
66
|
# 完全範囲を取得する
|
36
67
|
#
|
37
68
|
# @return [Array<Year>] 完全範囲
|
38
69
|
#
|
39
70
|
def get
|
71
|
+
return [] if invalid?
|
72
|
+
|
73
|
+
pre_get
|
74
|
+
|
40
75
|
years = FullRange.rearranged_years(annual_ranges: annual_ranges)
|
41
|
-
update_gengou(years: years)
|
76
|
+
years = update_gengou(years: years)
|
77
|
+
years = update_first_day(years: years)
|
78
|
+
|
79
|
+
post_get
|
80
|
+
|
81
|
+
years
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# 取得前処理
|
86
|
+
#
|
87
|
+
def pre_get
|
88
|
+
# FIXME: 別インスタンス変数を定義する方法は改善したい(ディープコピーにするか、get再取得を廃止するか)
|
89
|
+
@new_year_date_ = @new_year_date.clone
|
90
|
+
@multi_gengou_roller_ = @multi_gengou_roller.clone
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# 取得前処理
|
95
|
+
#
|
96
|
+
# 再取得に備えて、カウントアップした日付を元に戻す
|
97
|
+
#
|
98
|
+
def post_get
|
99
|
+
@new_year_date = @new_year_date_
|
100
|
+
@multi_gengou_roller = @multi_gengou_roller_
|
42
101
|
end
|
43
102
|
|
44
103
|
# :reek:TooManyStatements { max_statements: 6 }
|
@@ -109,6 +168,47 @@ module Zakuro
|
|
109
168
|
updated_years
|
110
169
|
end
|
111
170
|
|
171
|
+
#
|
172
|
+
# 月初日の西暦日を更新する
|
173
|
+
#
|
174
|
+
# @param [Array<Year>] years 完全範囲(月初日なし)
|
175
|
+
#
|
176
|
+
# @return [Array<Year>] 完全範囲(月初日あり)
|
177
|
+
#
|
178
|
+
def update_first_day(years:)
|
179
|
+
# TODO: リファクタリング
|
180
|
+
|
181
|
+
result = []
|
182
|
+
|
183
|
+
years.each do |year|
|
184
|
+
new_year_date = year.new_year_date.clone
|
185
|
+
date = new_year_date.clone
|
186
|
+
|
187
|
+
months = []
|
188
|
+
year.months.each do |month|
|
189
|
+
first_day = month.first_day
|
190
|
+
updated_month = Month.new(
|
191
|
+
month_label: month.month_label,
|
192
|
+
first_day: FirstDay.new(remainder: first_day.remainder,
|
193
|
+
western_date: date),
|
194
|
+
solar_terms: month.solar_terms
|
195
|
+
)
|
196
|
+
months.push(updated_month)
|
197
|
+
|
198
|
+
date = date.clone + updated_month.days
|
199
|
+
end
|
200
|
+
|
201
|
+
updated_year = Year.new(
|
202
|
+
multi_gengou: year.multi_gengou, new_year_date: new_year_date,
|
203
|
+
months: months, total_days: year.total_days
|
204
|
+
)
|
205
|
+
|
206
|
+
result.push(updated_year)
|
207
|
+
end
|
208
|
+
|
209
|
+
result
|
210
|
+
end
|
211
|
+
|
112
212
|
#
|
113
213
|
# 当年データを生成する
|
114
214
|
#
|