zakuro 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/lib/zakuro/calculation/base/multi_gengou.rb +101 -0
  3. data/lib/zakuro/calculation/base/multi_gengou_roller.rb +218 -0
  4. data/lib/zakuro/calculation/base/year.rb +107 -0
  5. data/lib/zakuro/calculation/cycle/abstract_remainder.rb +471 -0
  6. data/lib/zakuro/calculation/cycle/abstract_solar_term.rb +173 -0
  7. data/lib/zakuro/calculation/cycle/zodiac.rb +106 -0
  8. data/lib/zakuro/calculation/monthly/abstract_lunar_phase.rb +169 -0
  9. data/lib/zakuro/calculation/monthly/first_day.rb +45 -0
  10. data/lib/zakuro/calculation/monthly/initialized_month.rb +125 -0
  11. data/lib/zakuro/calculation/monthly/month.rb +187 -0
  12. data/lib/zakuro/calculation/monthly/month_label.rb +88 -0
  13. data/lib/zakuro/calculation/monthly/operated_month.rb +209 -0
  14. data/lib/zakuro/calculation/range/full_range.rb +210 -0
  15. data/lib/zakuro/calculation/range/medieval_annual_range.rb +105 -0
  16. data/lib/zakuro/calculation/range/operated_range.rb +144 -0
  17. data/lib/zakuro/calculation/range/operated_solar_terms.rb +201 -0
  18. data/lib/zakuro/calculation/range/transfer/western_date_allocation.rb +82 -0
  19. data/lib/zakuro/calculation/range/transfer/year_boundary.rb +146 -0
  20. data/lib/zakuro/calculation/specifier/single_day.rb +109 -0
  21. data/lib/zakuro/calculation/stella/lunar/abstract_location.rb +76 -0
  22. data/lib/zakuro/calculation/stella/lunar/choukei_value.rb +52 -0
  23. data/lib/zakuro/calculation/stella/solar/abstract_average.rb +117 -0
  24. data/lib/zakuro/calculation/stella/solar/abstract_location.rb +187 -0
  25. data/lib/zakuro/calculation/stella/solar/choukei_value.rb +136 -0
  26. data/lib/zakuro/calculation/summary/single.rb +129 -0
  27. data/lib/zakuro/calculation/type/old_float.rb +69 -0
  28. data/lib/zakuro/merchant.rb +2 -2
  29. data/lib/zakuro/operation/month/parser.rb +1 -1
  30. data/lib/zakuro/operation/month/type.rb +5 -10
  31. data/lib/zakuro/output/error.rb +7 -6
  32. data/lib/zakuro/output/logger.rb +50 -49
  33. data/lib/zakuro/output/response.rb +145 -144
  34. data/lib/zakuro/tools/typeof.rb +2 -2
  35. data/lib/zakuro/version.rb +1 -1
  36. data/lib/zakuro/version/abstract_version.rb +1 -1
  37. data/lib/zakuro/version/context.rb +23 -0
  38. data/lib/zakuro/version/gihou/const/number.rb +55 -0
  39. data/lib/zakuro/version/gihou/const/remainder.rb +56 -0
  40. data/lib/zakuro/version/gihou/cycle/remainder.rb +61 -0
  41. data/lib/zakuro/version/gihou/cycle/solar_term.rb +34 -0
  42. data/lib/zakuro/version/gihou/gihou.rb +23 -2
  43. data/lib/zakuro/version/gihou/monthly/lunar_phase.rb +106 -0
  44. data/lib/zakuro/version/gihou/range/annual_range.rb +39 -0
  45. data/lib/zakuro/version/gihou/stella/lunar/adjustment.rb +250 -0
  46. data/lib/zakuro/version/gihou/stella/lunar/localization.rb +44 -0
  47. data/lib/zakuro/version/gihou/stella/lunar/location.rb +86 -0
  48. data/lib/zakuro/version/gihou/stella/lunar/value.rb +74 -0
  49. data/lib/zakuro/version/gihou/stella/origin/average_november.rb +34 -0
  50. data/lib/zakuro/version/gihou/stella/origin/lunar_age.rb +62 -0
  51. data/lib/zakuro/version/gihou/stella/origin/winter_solstice.rb +55 -0
  52. data/lib/zakuro/version/gihou/stella/solar/adjustment.rb +93 -0
  53. data/lib/zakuro/version/gihou/stella/solar/average.rb +97 -0
  54. data/lib/zakuro/version/gihou/stella/solar/interval.rb +108 -0
  55. data/lib/zakuro/version/gihou/stella/solar/location.rb +61 -0
  56. data/lib/zakuro/version/gihou/stella/solar/value.rb +36 -0
  57. data/lib/zakuro/version/senmyou/const/number.rb +51 -0
  58. data/lib/zakuro/version/senmyou/const/remainder.rb +49 -0
  59. data/lib/zakuro/version/senmyou/cycle/remainder.rb +61 -0
  60. data/lib/zakuro/version/senmyou/cycle/solar_term.rb +34 -0
  61. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +80 -195
  62. data/lib/zakuro/version/senmyou/range/annual_range.rb +25 -170
  63. data/lib/zakuro/version/senmyou/senmyou.rb +10 -4
  64. data/lib/zakuro/version/senmyou/stella/lunar/adjustment.rb +237 -0
  65. data/lib/zakuro/version/senmyou/stella/lunar/localization.rb +44 -0
  66. data/lib/zakuro/version/senmyou/stella/lunar/location.rb +93 -0
  67. data/lib/zakuro/version/senmyou/stella/lunar/value.rb +66 -0
  68. data/lib/zakuro/version/senmyou/stella/origin/average_november.rb +34 -0
  69. data/lib/zakuro/version/senmyou/stella/origin/lunar_age.rb +62 -0
  70. data/lib/zakuro/version/senmyou/stella/origin/winter_solstice.rb +55 -0
  71. data/lib/zakuro/version/senmyou/stella/solar/adjustment.rb +93 -0
  72. data/lib/zakuro/version/senmyou/stella/solar/average.rb +97 -0
  73. data/lib/zakuro/version/senmyou/stella/solar/interval.rb +103 -0
  74. data/lib/zakuro/version/senmyou/stella/solar/location.rb +61 -0
  75. data/lib/zakuro/version/senmyou/stella/solar/value.rb +39 -0
  76. data/lib/zakuro/version/version_class_resolver.rb +66 -0
  77. data/lib/zakuro/version_factory.rb +2 -2
  78. metadata +64 -24
  79. data/lib/zakuro/cycle/abstract_remainder.rb +0 -456
  80. data/lib/zakuro/cycle/zodiac.rb +0 -103
  81. data/lib/zakuro/version/senmyou/base/era.rb +0 -83
  82. data/lib/zakuro/version/senmyou/base/multi_gengou.rb +0 -98
  83. data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +0 -217
  84. data/lib/zakuro/version/senmyou/base/remainder.rb +0 -60
  85. data/lib/zakuro/version/senmyou/base/solar_term.rb +0 -86
  86. data/lib/zakuro/version/senmyou/base/year.rb +0 -104
  87. data/lib/zakuro/version/senmyou/monthly/first_day.rb +0 -44
  88. data/lib/zakuro/version/senmyou/monthly/initialized_month.rb +0 -48
  89. data/lib/zakuro/version/senmyou/monthly/month.rb +0 -181
  90. data/lib/zakuro/version/senmyou/monthly/month_label.rb +0 -87
  91. data/lib/zakuro/version/senmyou/monthly/operated_month.rb +0 -167
  92. data/lib/zakuro/version/senmyou/range/full_range.rb +0 -324
  93. data/lib/zakuro/version/senmyou/range/operated_range.rb +0 -126
  94. data/lib/zakuro/version/senmyou/range/operated_solar_terms.rb +0 -181
  95. data/lib/zakuro/version/senmyou/specifier/single_day_specifier.rb +0 -102
  96. data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +0 -332
  97. data/lib/zakuro/version/senmyou/stella/solar_average.rb +0 -214
  98. data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +0 -394
  99. data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +0 -106
  100. data/lib/zakuro/version/senmyou/summary/single.rb +0 -125
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base/multi_gengou_roller'
4
+ require_relative '../base/year'
5
+
6
+ require_relative '../../era/western'
7
+ require_relative '../../output/response'
8
+ require_relative '../../output/logger'
9
+
10
+ # :nodoc:
11
+ module Zakuro
12
+ # :nodoc:
13
+ module Calculation
14
+ # :nodoc:
15
+ module Specifier
16
+ #
17
+ # SingleDay 一日検索
18
+ #
19
+ module SingleDay
20
+ # @return [Output::Logger] ロガー
21
+ LOGGER = Output::Logger.new(location: 'specifier')
22
+
23
+ #
24
+ # 取得する
25
+ #
26
+ # @param [Array<Year>] yeas 範囲
27
+ # @param [Western::Calendar] date 西暦日
28
+ #
29
+ # @return [Result::Data::SingleDay] 和暦日
30
+ #
31
+ def self.get(years: [], date: Western::Calendar.new)
32
+ year = specify_year(years: years, date: date)
33
+
34
+ year = transfer(year: year, date: date)
35
+
36
+ month = specify_month(year: year, date: date)
37
+ first_date = month.western_date
38
+
39
+ Output::Response::SingleDay.save_single_day(
40
+ param: Output::Response::SingleDay::Param.new(
41
+ year: year, month: month,
42
+ date: date, days: date - first_date
43
+ )
44
+ )
45
+ end
46
+
47
+ #
48
+ # 年を特定する
49
+ #
50
+ # @param [Array<Year>] years 範囲
51
+ # @param [Western::Calendar] date 西暦日
52
+ #
53
+ # @return [Year] 対象年
54
+ #
55
+ def self.specify_year(years:, date:)
56
+ years.reverse_each do |year|
57
+ return year if date >= year.new_year_date
58
+ end
59
+
60
+ raise ArgumentError, "invalid year range. date: #{date.format}"
61
+ end
62
+ private_class_method :specify_year
63
+
64
+ #
65
+ # 改元する
66
+ #
67
+ # @param [Year] year 年
68
+ # @param [Western::Calendar] date 西暦日
69
+ #
70
+ # @return [Year] 改元後の年
71
+ #
72
+ def self.transfer(year:, date:)
73
+ multi_gengou = Calculation::Base::MultiGengouRoller.transfer(
74
+ multi_gengou: year.multi_gengou, date: date
75
+ )
76
+ Calculation::Base::Year.new(
77
+ multi_gengou: multi_gengou, new_year_date: year.new_year_date,
78
+ months: year.months, total_days: year.total_days
79
+ )
80
+ end
81
+ private_class_method :transfer
82
+
83
+ # :reek:TooManyStatements { max_statements: 7 }
84
+
85
+ #
86
+ # 月を特定する
87
+ #
88
+ # @param [Year] year 年
89
+ # @param [Western::Calendar] date 西暦日
90
+ #
91
+ # @return [Month] 対象月
92
+ #
93
+ def self.specify_month(year:, date:)
94
+ months = year.months
95
+
96
+ current_month = months[0]
97
+ months.each do |month|
98
+ return current_month if month.western_date > date
99
+
100
+ current_month = month
101
+ end
102
+
103
+ current_month
104
+ end
105
+ private_class_method :specify_month
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../cycle/abstract_remainder'
4
+
5
+ # :nodoc:
6
+ module Zakuro
7
+ # :nodoc:
8
+ module Calculation
9
+ # :nodoc:
10
+ module Lunar
11
+ #
12
+ # AbstractLocation 入暦
13
+ #
14
+ class AbstractLocation
15
+ # @return [True] 計算済み(前回計算あり)
16
+ # @return [False] 未計算(初回計算)
17
+ attr_reader :calculated
18
+ # @return [Integer] 西暦年
19
+ attr_reader :western_year
20
+ # @return [Cycle::LunarRemainder] 大余小余(初回:昨年天正閏余)
21
+ attr_reader :remainder
22
+
23
+ #
24
+ # 初期化
25
+ #
26
+ # @param [Cycle::LunarRemainder] lunar_age 天正閏余(大余小余)
27
+ # @param [Integer] western_year 西暦年
28
+ #
29
+ def initialize(lunar_age:, western_year:)
30
+ @calculated = false
31
+ @western_year = western_year
32
+ @remainder = lunar_age
33
+ end
34
+
35
+ #
36
+ # 入暦を計算する
37
+ #
38
+ def run
39
+ # abstract
40
+ end
41
+
42
+ #
43
+ # 弦の分だけ月地点を進める
44
+ #
45
+ def add_quarter
46
+ # abstract
47
+ end
48
+
49
+ private
50
+
51
+ #
52
+ # 初回計算
53
+ #
54
+ def first
55
+ # abstract
56
+ end
57
+
58
+ #
59
+ # 大余小余に合わせて減算する(折り返す)
60
+ #
61
+ # @param [Cycle::LunarRemainder] limit 上限
62
+ #
63
+ def decrease(limit:)
64
+ # abstract
65
+ end
66
+
67
+ #
68
+ # 1始まりにする
69
+ #
70
+ def one_based
71
+ @remainder.add!(Cycle::AbstractRemainder.new(day: 1, minute: 0, second: 0))
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../type/old_float'
4
+
5
+ # :nodoc:
6
+ module Zakuro
7
+ # :nodoc:
8
+ module Calculation
9
+ # :nodoc:
10
+ module Lunar
11
+ #
12
+ # ChoukeiValue 再考長慶宣明暦算法
13
+ #
14
+ module ChoukeiValue
15
+ #
16
+ # 四捨五入した大余を返す
17
+ #
18
+ # @param [Integer] per 増減率
19
+ # @param [Integer] denominator 小余の分母
20
+ # @param [Integer] minute 小余
21
+ #
22
+ # @return [Integer] 累計値(大余)
23
+ #
24
+ def self.rounded_day(per:, denominator:, minute:)
25
+ remainder_minute = Type::OldFloat.new((per * minute).to_f)
26
+ day = day_only(remainder_minute: remainder_minute.get, denominator: denominator)
27
+ # 繰り上げ結果を足す
28
+ day += carried_minute(remainder_minute: remainder_minute, denominator: denominator)
29
+
30
+ day
31
+ end
32
+
33
+ def self.day_only(remainder_minute:, denominator:)
34
+ float_day = Type::OldFloat.new(remainder_minute / denominator)
35
+ # 切り捨て(プラスマイナスに関わらず小数点以下切り捨て)
36
+ float_day.floor!
37
+ float_day.get
38
+ end
39
+ private_class_method :day_only
40
+
41
+ def self.carried_minute(remainder_minute:, denominator:)
42
+ remainder_day = remainder_minute.abs % denominator
43
+ # 四捨五入(1/2日 以上なら繰り上げる)
44
+ return remainder_minute.sign if remainder_day >= (denominator / 2)
45
+
46
+ 0
47
+ end
48
+ private_class_method :carried_minute
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nodoc:
4
+ module Zakuro
5
+ # :nodoc:
6
+ module Calculation
7
+ # :nodoc:
8
+ module Solar
9
+ #
10
+ # AbstractAverage 平気(太陽軌道平均)
11
+ #
12
+ class AbstractAverage
13
+ #
14
+ # 初期化
15
+ #
16
+ # @param [Cycle::AbstractSolarTerm] solar_term 入定気
17
+ #
18
+ def initialize(solar_term:)
19
+ @solar_term = solar_term
20
+ end
21
+
22
+ #
23
+ # 冬至から数えた1年データの月ごとに二十四節気を割り当てる
24
+ #
25
+ # @param [Array<Month>] annual_range 1年データ
26
+ #
27
+ # @return [Array<Month>] 1年データ
28
+ #
29
+ def set(annual_range:)
30
+ # 次月と比較しながら当月の二十四節気を決める
31
+ # NOTE: 最後の月は処理できない(=計算外の余分な月が最後に必要である)
32
+ annual_range.each_cons(2) do |(current_month, next_month)|
33
+ set_solar_term(
34
+ current_month: current_month,
35
+ next_month: next_month
36
+ )
37
+ end
38
+
39
+ annual_range
40
+ end
41
+
42
+ # :reek:TooManyStatements { max_statements: 7 }
43
+
44
+ #
45
+ # 月内(当月朔日から当月末日(来月朔日の前日)の間)に二十四節気があるか
46
+ # @note 大余60で一巡するため 以下2パターンがある
47
+ # * current_month <= next_month : (二十四節気) >= current_month && (二十四節気) < next_month
48
+ # * current_month > next_month : (二十四節気) >= current_month || (二十四節気) < next_month
49
+ #
50
+ # @param [Cycle::AbstractRemainder] solar_term 二十四節気
51
+ # @param [Cycle::AbstractRemainder] current_month 月初
52
+ # @param [Cycle::AbstractRemainder] next_month 月末
53
+ #
54
+ # @return [True] 対象の二十四節気がある
55
+ # @return [False] 対象の二十四節気がない
56
+ #
57
+ def self.in_solar_term?(solar_term:, current_month:, next_month:)
58
+ # 大余で比較する
59
+ target_time = solar_term.day
60
+ current_month_time = current_month.day
61
+ next_month_time = next_month.day
62
+ current_month_over = (target_time >= current_month_time)
63
+ next_month_under = (target_time < next_month_time)
64
+
65
+ return current_month_over && next_month_under if current_month_time <= next_month_time
66
+
67
+ current_month_over || next_month_under
68
+ end
69
+
70
+ private
71
+
72
+ # :reek:TooManyStatements { max_statements: 8 }
73
+
74
+ #
75
+ # 二十四節気を設定する
76
+ #
77
+ # @param [Month] current_month 当月
78
+ # @param [Month] next_month 次月
79
+ #
80
+ def set_solar_term(current_month:, next_month:)
81
+ # 安全策として無限ループは回避する
82
+ # * 最大試行回数:4回(設定なし => 設定あり => 設定あり => 設定なし)
83
+ # * 閏月は1回しか設定しない
84
+ # * 最大2回設定する(中気・節気)
85
+ (0..3).each do |_index|
86
+ in_range = AbstractAverage.in_solar_term?(
87
+ solar_term: @solar_term.remainder, current_month: current_month.remainder,
88
+ next_month: next_month.remainder
89
+ )
90
+
91
+ # 範囲外
92
+ unless in_range
93
+ # 1つ以上設定されていれば切り上げる(一つ飛ばしで二十四節気を設定することはない)
94
+ break unless current_month.empty_solar_term?
95
+
96
+ next_solar_term
97
+ next
98
+ end
99
+
100
+ current_month.add_term(term: @solar_term.clone)
101
+ next_solar_term
102
+
103
+ # 定気は最大2つまで
104
+ break if current_month.solar_term_size == 2
105
+ end
106
+ end
107
+
108
+ #
109
+ # 次の二十四節気に移る
110
+ #
111
+ def next_solar_term
112
+ @solar_term.next_term!
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../cycle/abstract_remainder'
4
+
5
+ # :nodoc:
6
+ module Zakuro
7
+ # :nodoc:
8
+ module Calculation
9
+ # :nodoc:
10
+ module Solar
11
+ #
12
+ # AbstractLocation 入定気
13
+ #
14
+ class AbstractLocation
15
+ # @return [True] 計算済み(前回計算あり)
16
+ # @return [False] 未計算(初回計算)
17
+ attr_reader :calculated
18
+ # @return [Integer] 連番
19
+ attr_reader :index
20
+ # @return [Cycle::AbstractRemainder] 大余小余
21
+ attr_reader :remainder
22
+ # @return [Cycle::AbstractRemainder] 弦
23
+ attr_reader :quarter
24
+
25
+ #
26
+ # 初期化
27
+ #
28
+ # @param [Cycle::AbstractRemainder] lunar_age 天正閏余(大余小余)
29
+ # @param [Cycle::AbstractRemainder] quarter 弦
30
+ #
31
+ def initialize(lunar_age:, quarter:)
32
+ @calculated = false
33
+ @index = -1
34
+ @remainder = lunar_age.clone
35
+ @quarter = quarter
36
+ end
37
+
38
+ #
39
+ # 入定気を計算する
40
+ #
41
+ def run
42
+ return current if calculated
43
+
44
+ first
45
+ end
46
+
47
+ #
48
+ # 無効かどうか
49
+ #
50
+ # @return [True] 無効
51
+ # @return [False] 有効
52
+ #
53
+ def invalid?
54
+ @index == -1
55
+ end
56
+
57
+ #
58
+ # 弦の分だけ太陽地点を進める
59
+ #
60
+ def add_quarter
61
+ @remainder.add!(quarter)
62
+ end
63
+
64
+ #
65
+ # 二十四節気番号に対応する入気定日加減数を返す
66
+ #
67
+ # @note 継承で暦ごとの入気定日加減数を返す
68
+ #
69
+ # @param [Integer] index 二十四節気番号
70
+ #
71
+ # @return [Cycle::Remainder] 入気定日加減数
72
+ #
73
+ def interval(index:)
74
+ # abstract
75
+ end
76
+
77
+ #
78
+ # 入気定日加減数の要素数を返す
79
+ #
80
+ # @note 継承で暦ごとの入気定日加減数の要素数を返す
81
+ #
82
+ # @return [Integer] 入気定日加減数の要素数
83
+ #
84
+ def interval_size
85
+ # abstract
86
+ end
87
+
88
+ private
89
+
90
+ #
91
+ # 2回目以降の計算をする
92
+ #
93
+ def current
94
+ decrease_recursively
95
+ end
96
+
97
+ #
98
+ # 初回計算する
99
+ #
100
+ def first
101
+ define_first
102
+ @calculated = true
103
+ end
104
+
105
+ #
106
+ # 初回の入定気を定める
107
+ #
108
+ def define_first
109
+ # 入定気の起算方法
110
+ # 概要:
111
+ # * 太陽の運行による補正値は、二十四節気の気ごとに定められる
112
+ # * 11月経朔の前にある気を求め、それから11月経朔との間隔を求める
113
+ # * 気ごとの補正値と、気から11月経朔までにかかる補正値を求める
114
+ # 前提:
115
+ # * 11月経朔に関わる二十四節気は、時系列から順に、小雪・大雪・冬至である
116
+ # * 小雪〜大雪の間隔は小雪定数で、大雪〜冬至の間隔は大雪定数で決められている(24気損益眺朒(ちょうじく)数のこと)
117
+ # * 11月経朔は、この小雪〜冬至の間のいずれかにある
118
+ # 計算:
119
+ # 2パターンある
120
+ # (a) 大雪〜冬至にある場合
121
+ # *「大雪定数 >= 天正閏余」の場合を指す
122
+ # * * NOTE 資料では「より大きい(>)」とされるが、大雪そのものの場合は大雪から起算すべき
123
+ # * この場合は、大雪〜経朔の間隔を求める
124
+ # (b) 小雪〜大雪にある場合
125
+ # *「大雪定数 < 天正閏余」の場合を指す
126
+ # * この場合は、小雪〜経朔の間隔を求める
127
+
128
+ # NOTE: 上記パターンとは別に、稀だが立冬のパターンも存在する
129
+ # この場合は比較方法はそのままに立冬〜経朔の間隔を求める
130
+
131
+ # 大雪(23)/小雪(22)/立冬(21)
132
+ [23, 22, 21].each do |index|
133
+ prev(index: index)
134
+
135
+ break unless invalid?
136
+ end
137
+
138
+ # 立冬(21)を超える天正閏余は成立し得ない(1朔望月をはるかに超えることになる)
139
+ return unless invalid?
140
+
141
+ raise ArgumentError.new, 'invalid winster solstice age'
142
+ end
143
+
144
+ #
145
+ # 大余小余の分だけ二十四節気を遡る
146
+ #
147
+ # @param [Integer] index 二十四節気番号
148
+ #
149
+ def prev(index:)
150
+ interval = interval(index: index)
151
+ if remainder > interval
152
+ @remainder.sub!(interval)
153
+ return
154
+ end
155
+
156
+ # 入定気が確定する
157
+ @remainder = interval.sub(@remainder)
158
+ @index = index
159
+ end
160
+
161
+ #
162
+ # 二十四節気番号を次に進める
163
+ #
164
+ def next_index
165
+ @index += 1
166
+ @index = 0 if @index >= interval_size
167
+ end
168
+
169
+ #
170
+ # 二十四節気を減算する
171
+ #
172
+ def decrease_recursively
173
+ interval = interval(index: index)
174
+ # 現在の二十四節気に留まる
175
+ return if remainder < interval
176
+
177
+ @remainder.sub!(interval)
178
+
179
+ next_index
180
+
181
+ # 再帰
182
+ decrease_recursively
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end