Class: Zakuro::Calculation::Cycle::AbstractRemainder Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/zakuro/calculation/cycle/abstract_remainder.rb

Overview

This class is abstract.

大余小余計算に必要な処理を行う、暦に依存しない汎用的なクラス

大余小余(時刻情報)

  • 十干十二支(60日)を上限とした「日時分秒」の情報で、日付(date)/時刻(time)と部分的に重なる概念

  • 「15日1012分5秒」のような形式で表される

  • 分の上限で大余に繰り上げる

  • 秒の上限で1分に繰り上げる

Constant Summary collapse

LIMIT =

Returns 大余上限.

Returns:

  • (Integer)

    大余上限

60

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_day: -1,, base_minute: -1,, day: -1,, minute: -1,, second: -1,, total: -1)) ⇒ AbstractRemainder

初期化

Parameters:

  • base_day (Integer) (defaults to: -1,)

    1大余に必要な小余(暦によって基数が異なる)

  • base_minute (Integer) (defaults to: -1,)

    1小余に必要な秒(暦によって基数が異なる)

  • day (Integer) (defaults to: -1,)

    大余(“日”に相当)

  • minute (Integer) (defaults to: -1,)

    小余(“分”に相当)

  • second (Integer) (defaults to: -1,)

  • total (Integer) (defaults to: -1))

    繰り上げなしの小余



52
53
54
55
56
57
58
59
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 52

def initialize(base_day: -1, base_minute: -1, day: -1, minute: -1, second: -1, total: -1)
  @base_limit = LIMIT
  @base_day = base_day
  @base_minute = base_minute
  @limited = true

  set(day: day, minute: minute, second: second, total: total)
end

Instance Attribute Details

#base_dayInteger (readonly)

Returns 1大余に必要な小余(暦によって基数が異なる).

Returns:

  • (Integer)

    1大余に必要な小余(暦によって基数が異なる)



31
32
33
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 31

def base_day
  @base_day
end

#base_limitInteger (readonly)

Returns 繰り上げなしの小余.

Returns:

  • (Integer)

    繰り上げなしの小余



29
30
31
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 29

def base_limit
  @base_limit
end

#base_minuteInteger (readonly)

Returns 1小余に必要な秒(暦によって基数が異なる).

Returns:

  • (Integer)

    1小余に必要な秒(暦によって基数が異なる)



33
34
35
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 33

def base_minute
  @base_minute
end

#dayInteger (readonly)

Returns 大余(“日”に相当).

Returns:

  • (Integer)

    大余(“日”に相当)



23
24
25
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 23

def day
  @day
end

#limitedTrue, False (readonly)

繰り上げ有無

Returns:

  • (True)

    繰り上げあり

  • (False)

    繰り上げなし



37
38
39
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 37

def limited
  @limited
end

#minuteInteger (readonly)

Returns 小余(“分”に相当).

Returns:

  • (Integer)

    小余(“分”に相当)



25
26
27
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 25

def minute
  @minute
end

#secondInteger (readonly)

Returns 秒.

Returns:

  • (Integer)



27
28
29
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 27

def second
  @second
end

Instance Method Details

#!=(other) ⇒ True, False

大小比較(!=)

Parameters:

Returns:

  • (True)

    等しくない

  • (False)

    等しい



301
302
303
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 301

def !=(other)
  !eql?(other)
end

#<(other) ⇒ True, False

大小比較(<)

Parameters:

Returns:

  • (True)

    より小さい

  • (False)

    以上



265
266
267
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 265

def <(other)
  down?(other)
end

#<=(other) ⇒ True, False

大小比較(<=)

Parameters:

Returns:

  • (True)

    以下

  • (False)

    より大きい



277
278
279
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 277

def <=(other)
  down?(other) || eql?(other)
end

#==(other) ⇒ True, False

大小比較(==)

Parameters:

Returns:

  • (True)

    等しい

  • (False)

    等しくない



289
290
291
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 289

def ==(other)
  eql?(other)
end

#>(other) ⇒ True, False

大小比較(>)

Parameters:

Returns:

  • (True)

    より大きい

  • (False)

    以下



241
242
243
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 241

def >(other)
  up?(other)
end

#>=(other) ⇒ True, False

大小比較(>=)

Parameters:

Returns:

  • (True)

    以上

  • (False)

    より小さい



253
254
255
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 253

def >=(other)
  up?(other) || eql?(other)
end

#add(other) ⇒ AbstractRemainder

(非破壊的に)加算する

Parameters:

Returns:



154
155
156
157
158
159
160
161
162
163
164
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 154

def add(other)
  invalid?(param: other)
  sum_day = day + other.day
  sum_minute = minute + other.minute
  sum_second = second + other.second
  sum_day, sum_minute, sum_second = carry(
    sum_day, sum_minute, sum_second
  )

  clone.set(day: sum_day, minute: sum_minute, second: sum_second)
end

#add!(other) ⇒ AbstractRemainder

(破壊的に)加算する

Parameters:

Returns:



189
190
191
192
193
194
195
196
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 189

def add!(other)
  result = add(other)
  @day = result.day
  @minute = result.minute
  @second = result.second

  self
end

#add_day(term) ⇒ AbstractRemainder

(非破壊的に)大余のみを加算する

Parameters:

  • term (Integer)

    他の大余

Returns:



173
174
175
176
177
178
179
180
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 173

def add_day(term)
  sum_day = day + term
  sum_day, sum_minute, sum_second = carry(
    sum_day, minute, second
  )

  clone.set(day: sum_day, minute: sum_minute, second: sum_second)
end

#carry!AbstractRemainder

繰り上げる

Returns:



451
452
453
454
455
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 451

def carry!
  @day, @minute, @second = carry(day, minute, second)

  self
end

#float_minuteFloat

秒を含めた小余を返す

Returns:

  • (Float)

    小余



421
422
423
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 421

def float_minute
  minute + second.to_f / base_minute
end

#floor_minuteInteger

Note:

切り捨て前に繰り上げる

小余(秒切り捨て)を返す

Returns:

  • (Integer)

    小余(秒切り捨て)



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 366

def floor_minute
  result = float_minute
  # NOTE: 『日本暦日原典』に準じ、少数点以下桁数を2桁とし、3桁目は四捨五入する
  # これが判明したのは、月の運動による計算を行う際、下記の小余が±1ズレていたことによる
  #
  # ## 儀鳳暦
  # * 大宝 2年 5 大 丁卯 3-1129 702 5 31 (12)22-138 (11)6-1185
  # * 養老 3年 閏7 小 丁巳 53-767 719 8 20            (17)7-478
  #
  # ## 大衍暦
  # * 神護景雲 2年 5 小 甲辰 40-632 768 5 21 (12)8-363 (11)52-2739
  # * 仁寿 2年 10 大 癸亥 59-1781 852 11 15 (22)0-2538 (23)16-162
  #
  # ## 宣明暦
  # * 天暦 2年 7 小 戊申 44-8274 948 8 8 (16)53-690 (17)8-2525
  # * 仁平 2年 3 小 丙申 32-1497 1152 4 7 (8)41-2025 (9)56-3860
  # * 承久 2年 庚辰   2 小 壬戌 58-7037 1220 3 7 (6)7-3693 (7)22-5529
  # * 安貞 1年 8 大 丁未 43-5913 1227 9 12 (18)46-6506 (19)1-8341
  # * 永享 10年 12 大 辛亥 47-2832 1438 12 17 (2)15-1196 (1)59-7760
  #
  # これらは月の運行で表の引き当て時に使う大余小余のズレが原因だった
  # 小余は、小余と秒の合算値で求められるが、次の合算値が『日本暦日原典』で切り上げられていた
  #
  # ## 儀鳳暦
  # |小余|小余(秒 / 12)|合算|
  # |:----|:----|:----|
  # |950.4999913|0.5|950.9999913|
  # |390.7499913|0.25|390.9999913|
  #
  # ## 大衍暦
  # |小余|小余(秒 / 80)|合算|
  # |:----|:----|:----|
  # |1697.921259|0.075|1697.996259|
  # |2656.833759|0.1625|2656.996259|
  #
  # ## 宣明暦
  # |小余|小余(秒 / 100)|合算|
  # |:----|:----|:----|
  # |6291.709782|0.29|6291.999782|
  # |361.9497818|0.05|361.9997818|
  # |5470.569782|0.43|5470.999782|
  # |4552.089782|0.91|4552.999782|
  # |2161.659782|0.34|2161.999782|
  #
  # 従って、少数点以下桁数を2桁とし、3桁目は四捨五入することとした
  result = result.round(2)
  # 秒は切り捨てる
  result.floor
end

#format(form: '%d-%d') ⇒ String

特定の文字フォーマットにして出力する

Parameters:

  • form (String) (defaults to: '%d-%d')

    フォーマット(大余、小余、秒それぞれを%dで指定する)

Returns:

  • (String)

    フォーマットした結果



474
475
476
477
478
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 474

def format(form: '%d-%d')
  return '' if invalid?

  super(form, @day, @minute, @second)
end

#invalid?(param: self) ⇒ True, False

無効かどうか

Parameters:

  • param (AbstractRemainder) (defaults to: self)

    自クラスのインスタンス(デフォルトは自身の参照)

Returns:

  • (True)

    無効

  • (False)

    有効

Raises:

  • (ArgumentError)

    引数エラー



118
119
120
121
122
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 118

def invalid?(param: self)
  raise ArgumentError, 'unmatch parameter type' unless param.is_a?(AbstractRemainder)

  param.day == -1 || param.minute == -1 || param.second == -1
end

#lift_limitAbstractRemainder

繰り上げ処理を外す

Returns:



91
92
93
94
95
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 91

def lift_limit
  @limited = false

  self
end

#only_day?True, False

大余のみか

Returns:

  • (True)

    大余のみ

  • (False)

    小余、秒あり



463
464
465
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 463

def only_day?
  minute.zero? && second.zero?
end

#roundAbstractRemainder

大余に四捨五入した結果を返す(秒は除外する)

Returns:



430
431
432
433
434
435
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 430

def round
  sum_day = day
  sum_day += 1 if minute >= (base_day / 2)

  initialize(sum_day, 0, 0)
end

#same_remainder_divided_by_ten?(other:) ⇒ True, False

日が同じ十干かどうか(大小の月判定)

Parameters:

  • other (Integer)

    大余

Returns:

  • (True)

    当月朔日と翌月朔日が同じ十干(「大」の月)

  • (False)

    当月朔日と翌月朔日が異なる十干(「小」の月)



141
142
143
144
145
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 141

def same_remainder_divided_by_ten?(other:)
  remainder_day = day % LIMIT

  (remainder_day % 10) == (other % 10)
end

#set(day: -1,, minute: -1,, second: -1,, total: -1)) ⇒ AbstractRemainder

値を設定する

Parameters:

  • day (Integer) (defaults to: -1,)

    大余(“日”に相当)

  • minute (Integer) (defaults to: -1,)

    小余(“分”に相当)

  • second (Integer) (defaults to: -1,)

  • total (Integer) (defaults to: -1))

    繰り上げなしの小余

Returns:



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 72

def set(day: -1, minute: -1, second: -1, total: -1)
  @day = day
  @minute = minute
  @second = second

  if total != -1
    @day = (total.to_f / base_day).floor
    @minute = (total % base_day)
    @second = 0
  end

  self
end

#set_limitAbstractRemainder

繰り上げ処理を設定する

Returns:



102
103
104
105
106
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 102

def set_limit
  @limited = true

  self
end

#sub(other) ⇒ AbstractRemainder

(非破壊的に)除算する

Parameters:

Returns:



205
206
207
208
209
210
211
212
213
214
215
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 205

def sub(other)
  invalid?(param: other)
  sum_day = day - other.day
  sum_minute = minute - other.minute
  sum_second = second - other.second
  sum_day, sum_minute, sum_second = carry(
    sum_day, sum_minute, sum_second
  )

  clone.set(day: sum_day, minute: sum_minute, second: sum_second)
end

#sub!(other) ⇒ AbstractRemainder

(破壊的に)除算する

Parameters:

Returns:



224
225
226
227
228
229
230
231
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 224

def sub!(other)
  result = sub(other)
  @day = result.day
  @minute = result.minute
  @second = result.second

  self
end

#to_minuteInteger

小余に揃えた結果を返す(秒は除外する)

Returns:

  • (Integer)

    小余



355
356
357
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 355

def to_minute
  day * base_day + minute
end

#to_sString

文字化する

Returns:

  • (String)

    文字化



442
443
444
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 442

def to_s
  "大余(日): #{day}, 小余(分): #{minute}, 小余(秒): #{second}"
end

#up_on_new_moonAbstractRemainder

(非破壊的に)進朔する

進朔とは、朔の瞬間が1日の3/4すなわち夕方以降となる場合に、その日ではなく1日進めて翌日を1日目にする方法のことです。進朔するかどうかの基準時刻を進朔限といいます。宣明暦では1日8400分ですから、進朔限は6300分で、それ以降だと進朔されます。



320
321
322
323
324
325
326
327
328
329
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 320

def up_on_new_moon
  cloned = clone
  limit = (base_day * 3) / 4
  if minute >= limit
    sum_day, sum_minute, sum_second = carry((day + 1), minute, second)
    return cloned.set(day: sum_day, minute: sum_minute, second: sum_second)
  end

  cloned
end

#up_on_new_moon!AbstractRemainder

(破壊的に)進朔する

進朔とは、朔の瞬間が1日の3/4すなわち夕方以降となる場合に、その日ではなく1日進めて翌日を1日目にする方法のことです。進朔するかどうかの基準時刻を進朔限といいます。宣明暦では1日8400分ですから、進朔限は6300分で、それ以降だと進朔されます。



341
342
343
344
345
346
347
348
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 341

def up_on_new_moon!
  result = up_on_new_moon
  @day = result.day
  @minute = result.minute
  @second = result.second

  self
end

#zodiac_nameString

十干十二支名

Returns:

  • (String)

    十干十二支名



129
130
131
# File 'lib/zakuro/calculation/cycle/abstract_remainder.rb', line 129

def zodiac_name
  Cycle::Zodiac.day_name(day: day)
end