zakuro 0.0.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 +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
|