zakuro 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +9 -0
- data/.gitignore +69 -0
- data/.rspec +3 -0
- data/.rubocop.yml +14 -0
- data/.travis.yml +6 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +20 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/images/12/346/234/210/344/273/245/351/231/215/343/201/256/345/205/245/345/256/232/346/260/227.png +0 -0
- data/images/12/346/234/210/344/273/245/351/231/215/343/201/256/346/234/210/343/201/256/351/200/262/351/200/200.png +0 -0
- data/images/source/description.numbers +0 -0
- data/images//345/205/245/345/256/232/346/260/227/343/201/256/350/265/267/347/256/227.png +0 -0
- data/images//345/220/204/346/234/210/343/201/256/346/261/202/343/202/201/346/226/271.png +0 -0
- data/images//345/244/252/351/231/275/343/201/250/346/234/210.png +0 -0
- data/lib/zakuro.rb +9 -0
- data/lib/zakuro/condition.rb +239 -0
- data/lib/zakuro/cycle/abstract_remainder.rb +457 -0
- data/lib/zakuro/cycle/zodiac.rb +103 -0
- data/lib/zakuro/era/gengou/set-001-until-south.yaml +375 -0
- data/lib/zakuro/era/gengou/set-002-from-north.yaml +166 -0
- data/lib/zakuro/era/gengou/set-003-modern.yaml +12 -0
- data/lib/zakuro/era/japan.rb +630 -0
- data/lib/zakuro/era/western.rb +412 -0
- data/lib/zakuro/merchant.rb +57 -0
- data/lib/zakuro/output/error.rb +10 -0
- data/lib/zakuro/output/logger.rb +64 -0
- data/lib/zakuro/output/response.rb +170 -0
- data/lib/zakuro/output/result.rb +219 -0
- data/lib/zakuro/output/stringifier.rb +62 -0
- data/lib/zakuro/version.rb +7 -0
- data/lib/zakuro/version/abstract_version.rb +29 -0
- data/lib/zakuro/version/genka/genka.rb +19 -0
- data/lib/zakuro/version/gihou/gihou.rb +19 -0
- data/lib/zakuro/version/gregorio/gregorio.rb +19 -0
- data/lib/zakuro/version/houryaku/houryaku.rb +19 -0
- data/lib/zakuro/version/joukyou/joukyou.rb +19 -0
- data/lib/zakuro/version/kansei/kansei.rb +19 -0
- data/lib/zakuro/version/senmyou/README.md +586 -0
- data/lib/zakuro/version/senmyou/base/era.rb +81 -0
- data/lib/zakuro/version/senmyou/base/gengou.rb +210 -0
- data/lib/zakuro/version/senmyou/base/remainder.rb +60 -0
- data/lib/zakuro/version/senmyou/base/solar_term.rb +66 -0
- data/lib/zakuro/version/senmyou/base/year.rb +58 -0
- data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +220 -0
- data/lib/zakuro/version/senmyou/monthly/month.rb +112 -0
- data/lib/zakuro/version/senmyou/senmyou.rb +34 -0
- data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +332 -0
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +192 -0
- data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +398 -0
- data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +106 -0
- data/lib/zakuro/version/senmyou/summary/annual_data.rb +186 -0
- data/lib/zakuro/version/senmyou/summary/gengou_data.rb +294 -0
- data/lib/zakuro/version/taien/taien.rb +19 -0
- data/lib/zakuro/version/tenpou/tenpou.rb +19 -0
- data/lib/zakuro/version_factory.rb +59 -0
- data/zakuro.gemspec +31 -0
- metadata +106 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../output/logger'
|
4
|
+
|
5
|
+
# :nodoc:
|
6
|
+
module Zakuro
|
7
|
+
# :nodoc:
|
8
|
+
module Senmyou
|
9
|
+
# :reek:TooManyConstants
|
10
|
+
|
11
|
+
#
|
12
|
+
# WinterSolstice 冬至
|
13
|
+
#
|
14
|
+
module WinterSolstice
|
15
|
+
# @return [Integer] 統法(1日=8400分)
|
16
|
+
DAY = 8400
|
17
|
+
# @return [Integer] 朔望月
|
18
|
+
SYNODIC_MONTH = 248_057
|
19
|
+
# @return [Integer] 一年
|
20
|
+
YEAR = 3_068_055
|
21
|
+
# @return [Integer] 通余: (YEAR - DAY * 12 * 30) = 44055
|
22
|
+
REMAINDER_ALL_YEAR = 44_055
|
23
|
+
# @return [Integer] 旬周(60日) 8400 * 60
|
24
|
+
SIXTY_DAYS = 504_000
|
25
|
+
# @return [Integer] 積年(甲子夜半朔旦冬至〜暦の開始前)
|
26
|
+
TOTAL_YEAR = 7_070_138
|
27
|
+
# @return [Integer] 暦の開始年(長慶2年)
|
28
|
+
BEGIN_YEAR = 822
|
29
|
+
|
30
|
+
# @return [Logger] ロガー
|
31
|
+
LOGGER = Logger.new(location: 'winter_solstice')
|
32
|
+
|
33
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
34
|
+
|
35
|
+
#
|
36
|
+
# 対象年の前年の冬至を求める
|
37
|
+
#
|
38
|
+
# @param [Integer] western_year 西暦年
|
39
|
+
#
|
40
|
+
# @return [Remainder] 前年の冬至
|
41
|
+
#
|
42
|
+
def self.calc(western_year:)
|
43
|
+
# 積年の開始から対象年までの年数
|
44
|
+
total = TOTAL_YEAR + western_year - BEGIN_YEAR
|
45
|
+
remainder_year = total % SIXTY_DAYS
|
46
|
+
|
47
|
+
LOGGER.debug("[a01]:#{remainder_year}")
|
48
|
+
|
49
|
+
# 通余を使う
|
50
|
+
winter_solstice_minute = (remainder_year * REMAINDER_ALL_YEAR) % SIXTY_DAYS
|
51
|
+
|
52
|
+
LOGGER.debug("[a02]:#{winter_solstice_minute}")
|
53
|
+
|
54
|
+
Remainder.new(total: winter_solstice_minute)
|
55
|
+
end
|
56
|
+
|
57
|
+
# :reek:TooManyStatements { max_statements: 7 }
|
58
|
+
|
59
|
+
#
|
60
|
+
# 対象年の天正閏余(冬至より前にある11月経朔との差 = 月齢)を算出する
|
61
|
+
# 太陽と月の運動による補正値を算出し、その補正結果を返す
|
62
|
+
#
|
63
|
+
# @param [Integer] western_year 西暦年
|
64
|
+
#
|
65
|
+
# @return [Remainder] 天正閏余
|
66
|
+
#
|
67
|
+
def self.calc_moon_age(western_year:)
|
68
|
+
# 積年の開始から対象年までの年数
|
69
|
+
total = TOTAL_YEAR + western_year - BEGIN_YEAR
|
70
|
+
|
71
|
+
# 12朔望月に対する1年の余り(単位:分)
|
72
|
+
remainder_minute = YEAR - (SYNODIC_MONTH * 12)
|
73
|
+
|
74
|
+
# 朔望月に含まれなかった余り(単位:年)
|
75
|
+
remainder_year = total % SYNODIC_MONTH
|
76
|
+
|
77
|
+
LOGGER.debug("[b01]: #{remainder_year}")
|
78
|
+
|
79
|
+
# 天正閏余
|
80
|
+
winter_solstice_age = remainder_minute * remainder_year % SYNODIC_MONTH
|
81
|
+
|
82
|
+
LOGGER.debug("[b02]: #{winter_solstice_age}")
|
83
|
+
|
84
|
+
# 大余・小余に変換する
|
85
|
+
Remainder.new(total: winter_solstice_age)
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# 11月経朔(冬至が含まれる月の1日)を求める
|
90
|
+
#
|
91
|
+
# @param [Integer] western_year 西暦年
|
92
|
+
#
|
93
|
+
# @return [Remainder] 11月経朔
|
94
|
+
#
|
95
|
+
def self.calc_averaged_last_november_1st(western_year:)
|
96
|
+
# 冬至
|
97
|
+
winter_solstice = calc(western_year: western_year)
|
98
|
+
# 天正閏余
|
99
|
+
winter_solstice_age = calc_moon_age(western_year: western_year)
|
100
|
+
|
101
|
+
# 11月経朔
|
102
|
+
winter_solstice.sub(winter_solstice_age)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../output/logger'
|
4
|
+
require_relative '../base/remainder'
|
5
|
+
require_relative '../monthly/month'
|
6
|
+
require_relative '../base/solar_term'
|
7
|
+
require_relative '../monthly/lunar_phase'
|
8
|
+
require_relative '../stella/solar_orbit'
|
9
|
+
require_relative '../stella/solar_average'
|
10
|
+
require_relative '../stella/lunar_orbit'
|
11
|
+
|
12
|
+
# :nodoc:
|
13
|
+
module Zakuro
|
14
|
+
# :nodoc:
|
15
|
+
module Senmyou
|
16
|
+
# AnnualData 年間データ
|
17
|
+
module AnnualData
|
18
|
+
# @return [Logger] ロガー
|
19
|
+
LOGGER = Logger.new(location: 'annual_data')
|
20
|
+
|
21
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
22
|
+
|
23
|
+
#
|
24
|
+
# 11月定朔(冬至が含まれる月の1日:補正済)を求める
|
25
|
+
#
|
26
|
+
# @param [Integer] western_year 西暦年
|
27
|
+
#
|
28
|
+
# @return [Remainder] 11月定朔
|
29
|
+
#
|
30
|
+
def self.calc_last_november_1st(western_year:)
|
31
|
+
# 天正閏余
|
32
|
+
winter_solstice_age = \
|
33
|
+
WinterSolstice.calc_moon_age(western_year: western_year)
|
34
|
+
# 11月経朔
|
35
|
+
november_1st = \
|
36
|
+
WinterSolstice.calc_averaged_last_november_1st(western_year: western_year)
|
37
|
+
# 11月定朔
|
38
|
+
|
39
|
+
# 補正
|
40
|
+
correction_value = correction_value_on_last_november_1st(
|
41
|
+
winter_solstice_age: winter_solstice_age,
|
42
|
+
western_year: western_year
|
43
|
+
)
|
44
|
+
|
45
|
+
result = november_1st.add(Remainder.new(day: 0, minute: correction_value,
|
46
|
+
second: 0))
|
47
|
+
# 進朔
|
48
|
+
result.up_on_new_moon!
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
53
|
+
|
54
|
+
#
|
55
|
+
# 一覧取得する
|
56
|
+
#
|
57
|
+
# * 対象年に対して、前年11月-当年11月までを出力する
|
58
|
+
# * 対象年(西暦)と計算年(元号x年)の紐付けは行わない
|
59
|
+
#
|
60
|
+
# @param [Integer] western_year 西暦年
|
61
|
+
#
|
62
|
+
# @return [Array<Month>] 1年データ
|
63
|
+
#
|
64
|
+
def self.collect_annual_data_after_last_november_1st(western_year:)
|
65
|
+
annual_data = initialized_annual_data(western_year: western_year)
|
66
|
+
|
67
|
+
apply_big_and_small_of_the_month(annual_data: annual_data)
|
68
|
+
|
69
|
+
SolarAverage.set_solar_terms_into_annual_data(western_year: western_year,
|
70
|
+
annual_data: annual_data)
|
71
|
+
|
72
|
+
# 月間隔を取得するためだけの末尾要素を削除
|
73
|
+
annual_data.pop
|
74
|
+
|
75
|
+
adjust_leap_month(annual_data: annual_data)
|
76
|
+
|
77
|
+
annual_data
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# 11月定朔の補正値を求める
|
82
|
+
#
|
83
|
+
# @param [Remainder] winter_solstice_age 天正閏余
|
84
|
+
# @param [Integer] western_year 西暦年
|
85
|
+
#
|
86
|
+
# @return [Integer] 補正値
|
87
|
+
#
|
88
|
+
def self.correction_value_on_last_november_1st(winter_solstice_age:, western_year:)
|
89
|
+
# 補正
|
90
|
+
solar_term = SolarTerm.new(
|
91
|
+
remainder: winter_solstice_age
|
92
|
+
)
|
93
|
+
solar_term = \
|
94
|
+
SolarOrbit.calc_solar_term_by_remainder(
|
95
|
+
solar_term: solar_term
|
96
|
+
)
|
97
|
+
|
98
|
+
moon_remainder, is_forward = LunarOrbit.calc_moon_point(
|
99
|
+
remainder: winter_solstice_age, western_year: western_year
|
100
|
+
)
|
101
|
+
|
102
|
+
SolarOrbit.calc_sun_orbit_value(solar_term: solar_term) +
|
103
|
+
LunarOrbit.calc_moon_orbit_value(remainder_month: moon_remainder,
|
104
|
+
is_forward: is_forward)
|
105
|
+
end
|
106
|
+
private_class_method :correction_value_on_last_november_1st
|
107
|
+
|
108
|
+
#
|
109
|
+
# 1年データを取得する
|
110
|
+
#
|
111
|
+
# @param [Integer] western_year 西暦年
|
112
|
+
#
|
113
|
+
# @return [Array<Month>] 1年データ
|
114
|
+
#
|
115
|
+
def self.initialized_annual_data(western_year:)
|
116
|
+
result = []
|
117
|
+
lunar_phase = LunarPhase.new(western_year: western_year)
|
118
|
+
|
119
|
+
is_last_year = true
|
120
|
+
|
121
|
+
monthes = [11, 12] + [*1..12]
|
122
|
+
|
123
|
+
monthes.each do |month|
|
124
|
+
LOGGER.debug('---', "month: #{month}", "is_last_year: #{is_last_year}")
|
125
|
+
|
126
|
+
adjusted = lunar_phase.next_month
|
127
|
+
|
128
|
+
result.push(
|
129
|
+
Month.new(is_last_year: is_last_year, number: month,
|
130
|
+
remainder: adjusted, phase_index: 0)
|
131
|
+
)
|
132
|
+
is_last_year = false if month == 12
|
133
|
+
end
|
134
|
+
result
|
135
|
+
end
|
136
|
+
private_class_method :initialized_annual_data
|
137
|
+
|
138
|
+
#
|
139
|
+
# 1年データの各月に月の大小を設定する
|
140
|
+
#
|
141
|
+
# @param [Array<Month>] annual_data 1年データ
|
142
|
+
#
|
143
|
+
def self.apply_big_and_small_of_the_month(annual_data:)
|
144
|
+
size = annual_data.size - 1
|
145
|
+
(0...size).each do |idx|
|
146
|
+
current_month = annual_data[idx]
|
147
|
+
next_month = annual_data[idx + 1]
|
148
|
+
current_month.is_many_days = \
|
149
|
+
current_month.remainder.same_remainder_divided_by_ten?(
|
150
|
+
other: next_month.remainder.day
|
151
|
+
)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
private_class_method :apply_big_and_small_of_the_month
|
155
|
+
|
156
|
+
# :reek:TooManyStatements { max_statements: 10 }
|
157
|
+
|
158
|
+
#
|
159
|
+
# 閏月が存在した場合に以降の月を1つずつ減らす
|
160
|
+
# @example 7,8,9 と続く月の8月が閏の場合、7, 閏7, 8 となる
|
161
|
+
#
|
162
|
+
# @param [Array<Month>] annual_data 1年データ
|
163
|
+
#
|
164
|
+
def self.adjust_leap_month(annual_data:)
|
165
|
+
# 閏による月の再調整を行う
|
166
|
+
leaped = false
|
167
|
+
annual_data.each do |month|
|
168
|
+
if month.even_term.invalid?
|
169
|
+
month.leaped = true
|
170
|
+
leaped = true
|
171
|
+
end
|
172
|
+
next unless leaped
|
173
|
+
|
174
|
+
# NOTE: 常気法では閏月は2-3年に一度のため、1年に二度発生しない前提
|
175
|
+
number = month.number - 1
|
176
|
+
if number <= 0
|
177
|
+
month.is_last_year = true
|
178
|
+
number = 12
|
179
|
+
end
|
180
|
+
month.number = number
|
181
|
+
end
|
182
|
+
end
|
183
|
+
private_class_method :adjust_leap_month
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../era/western'
|
4
|
+
require_relative 'annual_data'
|
5
|
+
require_relative '../../../output/response'
|
6
|
+
require_relative '../base/era'
|
7
|
+
require_relative '../base/gengou'
|
8
|
+
require_relative '../base/year'
|
9
|
+
|
10
|
+
# :nodoc:
|
11
|
+
module Zakuro
|
12
|
+
# :nodoc:
|
13
|
+
module Senmyou
|
14
|
+
#
|
15
|
+
# GengouData 元号の年情報
|
16
|
+
#
|
17
|
+
module GengouData
|
18
|
+
def self.get_ancient_date(date: Western::Calendar.new)
|
19
|
+
SingleDay.get_ancient_date(date: date)
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# SingleDay 1日データ
|
24
|
+
#
|
25
|
+
module SingleDay
|
26
|
+
#
|
27
|
+
# 1日データを取得する
|
28
|
+
#
|
29
|
+
# @param [Western::Calendar] date 年月日情報(西暦)
|
30
|
+
#
|
31
|
+
# @return [Response::SingleDay] 1日データ
|
32
|
+
#
|
33
|
+
def self.get_ancient_date(date: Western::Calendar.new)
|
34
|
+
raise ArgumentError, 'invalid senmyou date' unless Era.include?(date: date)
|
35
|
+
|
36
|
+
target = get_target(year_list: get_year_list(date: date), date: date)
|
37
|
+
|
38
|
+
Response::SingleDay.save_single_day(
|
39
|
+
param: Response::SingleDay::Param.new(
|
40
|
+
year: target.year, month: target.month,
|
41
|
+
date: target.date, days: target.days
|
42
|
+
)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Target 対象
|
48
|
+
#
|
49
|
+
class Target
|
50
|
+
# @return [Year] 年
|
51
|
+
attr_reader :year
|
52
|
+
# @return [Month] 月
|
53
|
+
attr_reader :month
|
54
|
+
# @return [Western::Calendar] 日
|
55
|
+
attr_reader :date
|
56
|
+
# @return [Integer] 月初からの日数
|
57
|
+
attr_reader :days
|
58
|
+
|
59
|
+
#
|
60
|
+
# 初期化
|
61
|
+
#
|
62
|
+
# @param [Year] year 年
|
63
|
+
# @param [Month] month 月
|
64
|
+
# @param [Western::Calendar] date 日
|
65
|
+
# @param [Integer] days 月初からの日数
|
66
|
+
#
|
67
|
+
def initialize(year:, month:, date:, days:)
|
68
|
+
@year = year
|
69
|
+
@month = month
|
70
|
+
@date = date
|
71
|
+
@days = days
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# MonthSearchResult 1年内に該当する月を検索した結果
|
77
|
+
#
|
78
|
+
class MonthSearchResult
|
79
|
+
# @return [Month] 月
|
80
|
+
attr_reader :target_month
|
81
|
+
# @return [Western::Calendar] 月初日
|
82
|
+
attr_reader :first_date
|
83
|
+
# @return [True] 該当データ引き当て済
|
84
|
+
# @return [False] 該当データ引き当てなし
|
85
|
+
attr_reader :breaked
|
86
|
+
|
87
|
+
#
|
88
|
+
# 初期化
|
89
|
+
#
|
90
|
+
# @param [Month] target_month 月
|
91
|
+
# @param [Western::Calendar] first_date 月初日
|
92
|
+
# @param [True, False] breaked 該当データ引き当て
|
93
|
+
#
|
94
|
+
def initialize(target_month: Month.new,
|
95
|
+
first_date: Western::Calendar.new, breaked:)
|
96
|
+
@target_month = target_month
|
97
|
+
@first_date = first_date
|
98
|
+
@breaked = breaked
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# 指定日に関連する暦の範囲だけ年データを生成する
|
104
|
+
#
|
105
|
+
# @param [Western::Calendar] date 西暦日
|
106
|
+
#
|
107
|
+
# @return [Array<Year>] 年データ
|
108
|
+
#
|
109
|
+
def self.get_year_list(date:)
|
110
|
+
# 元号の最初の年月日を取る
|
111
|
+
gengou = Gengou.new(date: date.clone)
|
112
|
+
|
113
|
+
# 南北朝には元号が2つ並び、必ずしも範囲が重ならないケースもある
|
114
|
+
# 対象日付に重なる元号から論理和の範囲を取り、処理漏れがないようにする
|
115
|
+
start_date = gengou.first_date.clone
|
116
|
+
# 最後の年は翌年から今年の冬至を求めるため範囲を1年広げる
|
117
|
+
newest_date = gengou.choise_newest_gengou_date.next_year
|
118
|
+
|
119
|
+
Series.get_year_list(
|
120
|
+
start_gengou: gengou, start_date: start_date, end_date: newest_date
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# 対象を引き当てる
|
126
|
+
#
|
127
|
+
# @param [Array<Year>] year_list 年データ
|
128
|
+
# @param [Western::Calendar] date 西暦日
|
129
|
+
#
|
130
|
+
# @return [Target] 対象
|
131
|
+
#
|
132
|
+
def self.get_target(year_list:, date:)
|
133
|
+
# 対象年/対象月を引き当てる
|
134
|
+
year_list.each do |year|
|
135
|
+
result = get_target_month(date: date, year: year)
|
136
|
+
|
137
|
+
next unless result.breaked
|
138
|
+
|
139
|
+
return Target.new(
|
140
|
+
year: year, month: result.target_month, date: date,
|
141
|
+
# 対象日に調整する
|
142
|
+
days: date - result.first_date
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
raise ArgumentError, "invalid range: #{date.format}"
|
147
|
+
end
|
148
|
+
|
149
|
+
# :reek:TooManyStatements { max_statements: 6 }
|
150
|
+
|
151
|
+
#
|
152
|
+
# 対象の月を引き当てる
|
153
|
+
#
|
154
|
+
# @param [Western::Calendar] date 西暦日
|
155
|
+
# @param [Year] year 年
|
156
|
+
#
|
157
|
+
# @return [MonthSearchResult] 1年内に該当する月を検索した結果
|
158
|
+
#
|
159
|
+
def self.get_target_month(date:, year:)
|
160
|
+
first_date = year.gengou.first_date.clone
|
161
|
+
year.months.each do |month|
|
162
|
+
# 月末の日付を超える場合
|
163
|
+
next_first_date = first_date.clone + month.days
|
164
|
+
if date < next_first_date
|
165
|
+
return MonthSearchResult.new(target_month: month,
|
166
|
+
first_date: first_date, breaked: true)
|
167
|
+
end
|
168
|
+
first_date = next_first_date
|
169
|
+
end
|
170
|
+
MonthSearchResult.new(breaked: false)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# Series 和暦時系列データ
|
176
|
+
#
|
177
|
+
module Series
|
178
|
+
# :reek:TooManyInstanceVariables { max_instance_variables: 6 }
|
179
|
+
|
180
|
+
#
|
181
|
+
# TimeAdvance 時間進行
|
182
|
+
#
|
183
|
+
class TimeAdvance
|
184
|
+
#
|
185
|
+
# 初期化
|
186
|
+
#
|
187
|
+
# @param [Gengou] start_gengou 開始元号
|
188
|
+
# @param [Western::Calendar] start_date 開始日
|
189
|
+
# @param [Western::Calendar] end_date 終了日
|
190
|
+
#
|
191
|
+
def initialize(start_gengou:, start_date:, end_date:)
|
192
|
+
@current_date = start_date.clone
|
193
|
+
@end_date = end_date
|
194
|
+
@year_list = []
|
195
|
+
@western_year = start_date.year
|
196
|
+
@year = Year.new(gengou: start_gengou)
|
197
|
+
end
|
198
|
+
|
199
|
+
#
|
200
|
+
# 年データを収集する
|
201
|
+
#
|
202
|
+
# @return [Array<Year>] 年データ
|
203
|
+
#
|
204
|
+
def collect_year_list
|
205
|
+
push_current_year
|
206
|
+
|
207
|
+
# 2年目以降
|
208
|
+
while @current_date <= @end_date
|
209
|
+
compensate_last_year
|
210
|
+
|
211
|
+
push_current_year
|
212
|
+
end
|
213
|
+
|
214
|
+
@year_list
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
|
219
|
+
#
|
220
|
+
# 1年データを収集する
|
221
|
+
#
|
222
|
+
# @return [Array<Month>] 1年データ
|
223
|
+
#
|
224
|
+
def collect_annual_data
|
225
|
+
AnnualData.collect_annual_data_after_last_november_1st(
|
226
|
+
western_year: @western_year
|
227
|
+
)
|
228
|
+
end
|
229
|
+
|
230
|
+
#
|
231
|
+
# 昨年データの不足分を補完する
|
232
|
+
# 昨年11月1日から今年1月1日の前日のデータを1年前データとする
|
233
|
+
#
|
234
|
+
# @return [<Type>] <description>
|
235
|
+
#
|
236
|
+
def compensate_last_year
|
237
|
+
last_year = @year_list[@year_list.size - 1]
|
238
|
+
collect_annual_data.each do |month|
|
239
|
+
next unless month.is_last_year
|
240
|
+
|
241
|
+
# 昨年の月データのみ
|
242
|
+
last_year.push(month: month)
|
243
|
+
@current_date += month.days
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# :reek:TooManyStatements { max_statements: 7 }
|
248
|
+
|
249
|
+
#
|
250
|
+
# 当年データを生成する
|
251
|
+
#
|
252
|
+
def push_current_year
|
253
|
+
next_year
|
254
|
+
collect_annual_data.each do |month|
|
255
|
+
next if month.is_last_year
|
256
|
+
|
257
|
+
@year.push(month: month)
|
258
|
+
@current_date += month.days
|
259
|
+
end
|
260
|
+
@year_list.push(@year)
|
261
|
+
|
262
|
+
@western_year += 1
|
263
|
+
end
|
264
|
+
|
265
|
+
#
|
266
|
+
# 次の元号年を取得する
|
267
|
+
#
|
268
|
+
def next_year
|
269
|
+
return if @year_list.empty?
|
270
|
+
|
271
|
+
@year = Year.new(gengou: @year.gengou.next_year)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
#
|
276
|
+
# 期間内の年データ全てを返す
|
277
|
+
#
|
278
|
+
# @param [Gengou] start_gengou 開始元号
|
279
|
+
# @param [Western::Calendar] start_date 開始日
|
280
|
+
# @param [Western::Calendar] end_date 終了日
|
281
|
+
#
|
282
|
+
# @return [Array<Year>] 年データ
|
283
|
+
#
|
284
|
+
def self.get_year_list(start_gengou:, start_date:, end_date:)
|
285
|
+
advance = TimeAdvance.new(
|
286
|
+
start_gengou: start_gengou, start_date: start_date, end_date: end_date
|
287
|
+
)
|
288
|
+
|
289
|
+
advance.collect_year_list
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|