class LunarDate

Constants

CALENDAR_YEAR_INFO_MAP
KOREAN_LUNAR_YEAR_INFO
LUNARDAYS_FOR_MONTHTYPE
MAX_YEAR_NUMBER
SOLAR_START_DATE

Attributes

day[RW]
is_leap_month[RW]
month[RW]
year[RW]

Public Class Methods

from_solar(year, month, day, calendar_symbol = :ko) click to toggle source
# File lib/ruby_lunardate.rb, line 16
def self.from_solar(year, month, day, calendar_symbol = :ko)
  solar_date = Date.new(year, month, day)
  days = get_days(solar_date)
  lunar_from_days(days, calendar_symbol)
end
new(year, month, day, is_leap_month = false) click to toggle source
# File lib/ruby_lunardate.rb, line 224
def initialize(year, month, day, is_leap_month = false)
  self.year = year
  self.month = month
  self.day = day
  self.is_leap_month = is_leap_month
end
to_solar(year, month, day, is_leap_month = false, calendar_symbol = :ko) click to toggle source
# File lib/ruby_lunardate.rb, line 22
def self.to_solar(year, month, day, is_leap_month = false, calendar_symbol = :ko)
  days = 0
  year_diff = year - 1900
  year_info = CALENDAR_YEAR_INFO_MAP[calendar_symbol]

  year_diff.times do |year_idx|
    days += year_info[year_idx][0]
  end

  (month - 1).times do |month_idx|
    total, _normal, _leap = lunardays_for_type(year_info[year_diff][month_idx + 1])
    days += total
  end

  days += (day - 1)

  if is_leap_month && year_info[year_diff][month] > 2
    days += lunardays_for_type(year_info[year_diff][month])[1]
  end

  solar_date = SOLAR_START_DATE + days
end

Private Class Methods

get_days(solar_date) click to toggle source
# File lib/ruby_lunardate.rb, line 238
def get_days(solar_date)
  (solar_date - SOLAR_START_DATE).to_i
end
in_this_days?(days, left_days) click to toggle source
# File lib/ruby_lunardate.rb, line 242
def in_this_days?(days, left_days)
  (days - left_days) < 0
end
lunar_from_days(days, calendar_symbol) click to toggle source
# File lib/ruby_lunardate.rb, line 246
def lunar_from_days(days, calendar_symbol)
  start_year = 1900
  target_month = 0
  is_leap_month = false
  matched = false
  year_info = CALENDAR_YEAR_INFO_MAP[calendar_symbol]

  MAX_YEAR_NUMBER.times do |year_idx|
    year_days = year_info[year_idx][0]
    if in_this_days?(days, year_days)
      12.times do |month_idx|
        total, normal, _leap = lunardays_for_type(year_info[year_idx][month_idx + 1])
        if in_this_days?(days, total)
          unless in_this_days?(days, normal)
            days -= normal
            is_leap_month = true
          end

          matched = true
          break
        end

        days -= total
        target_month += 1
      end
    end

    break if matched

    days -= year_days
    start_year += 1
  end

  lunar_date = new(start_year, target_month + 1, days + 1, is_leap_month)

  lunar_date
end
lunardays_for_type(month_type) click to toggle source
# File lib/ruby_lunardate.rb, line 234
def lunardays_for_type(month_type)
  LUNARDAYS_FOR_MONTHTYPE[month_type]
end

Public Instance Methods

inspect() click to toggle source
# File lib/ruby_lunardate.rb, line 49
def inspect
  to_s
end
to_s() click to toggle source
# File lib/ruby_lunardate.rb, line 45
def to_s
  format('%4d%02d%02d', year, month, day)
end