class Wareki::Date

Wareki date handling class, main implementation.

Attributes

day[RW]
era_name[RW]
era_year[RW]
month[RW]
year[RW]

Public Class Methods

_check_invalid_date(era, year, month, day) click to toggle source
# File lib/wareki/date.rb, line 17
def self._check_invalid_date(era, year, month, day)
  month == 12 or return true
  day > 2 or return true
  (era == '明治' && year == 5 ||
   %w(皇紀 神武天皇即位紀元).member?(era) &&
   year == GREGORIAN_START_YEAR - IMPERIAL_START_YEAR - 1) and
    return false
  true
end
_parse(str) click to toggle source
# File lib/wareki/date.rb, line 27
def self._parse(str)
  str = str.to_s.gsub(/[[:space:]]/, '')
  match = REGEX.match(str)
  match && !match[0].empty? or
    raise ArgumentError, "Invaild Date: #{str}"
  era = match[:era_name]
  if (era.nil? || era == '') && match[:year].nil?
    year = Date.today.year
  else
    (year = Utils.k2i(match[:year])) > 0 or
      raise ArgumentError, "Invalid year: #{str}"
  end
  month = day = 1

  era.to_s != '' && era.to_s != '紀元前' && !ERA_BY_NAME[era] and
    raise ArgumentError, "Date parse failed: Invalid era name '#{match[:era_name]}'"

  if match[:month]
    month = Utils.k2i(match[:month])
  elsif match[:alt_month]
    month = Utils.alt_month_name_to_i(match[:alt_month])
  end

  month > 12 || month < 1 and
    raise ArgumentError, "Invalid month: #{str}"

  if match[:day]
    if match[:day] == '晦'
      day = Utils.last_day_of_month(ERA_BY_NAME[era].year + year - 1, month, match[:is_leap])
    else
      day = Utils.k2i(match[:day])
    end
  end

  _check_invalid_date(era, year, month, day) or
    raise ArgumentError, "Invaild Date: #{str}"

  {era: era, year: year, month: month, day: day, is_leap: !!match[:is_leap]}
end
date(date) click to toggle source
# File lib/wareki/date.rb, line 81
def self.date(date)
  jd(date.jd)
end
imperial(year, month = 1, day = 1, is_leap_month = false) click to toggle source
# File lib/wareki/date.rb, line 85
def self.imperial(year, month = 1, day = 1, is_leap_month = false)
  new('皇紀', year, month, day, is_leap_month)
end
jd(d) click to toggle source
# File lib/wareki/date.rb, line 72
def self.jd(d)
  era = Utils.find_era(d)
  era or raise UnsupportedDateRange, "Cannot find era for date #{d.inspect}"
  year, month, day, is_leap = Utils.find_date_ary(d)
  obj = new(era.name, year - era.year + 1, month, day, is_leap)
  obj.__set_jd(d)
  obj
end
new(era_name, era_year, month = 1, day = 1, is_leap_month = false) click to toggle source
# File lib/wareki/date.rb, line 89
def initialize(era_name, era_year, month = 1, day = 1, is_leap_month = false)
  raise ArgumentError, "Undefined era '#{era_name}'" if
    era_name.to_s != '' && era_name != '紀元前' && !ERA_BY_NAME[era_name]

  @month = month
  @day = day
  @is_leap_month = is_leap_month
  @era_name = era_name
  @era_year = era_year
  if era_name.to_s == '' || era_name == '西暦'
    @year = @era_year
  elsif era_name.to_s == '紀元前'
    @year = -@era_year
  elsif %w(皇紀 神武天皇即位紀元).include? era_name
    @year = era_year + IMPERIAL_START_YEAR
  else
    @year = ERA_BY_NAME[era_name].year + era_year - 1
  end
end
parse(str) click to toggle source
# File lib/wareki/date.rb, line 67
def self.parse(str)
  di = _parse(str)
  new(di[:era], di[:year], di[:month], di[:day], di[:is_leap])
end
today() click to toggle source
# File lib/wareki/date.rb, line 13
def self.today
  jd(::Date.today.jd)
end

Public Instance Methods

+(other) click to toggle source
# File lib/wareki/date.rb, line 246
def +(other)
  self.class.jd jd + _to_jd_for_calc(other)
end
-(other) click to toggle source
# File lib/wareki/date.rb, line 242
def -(other)
  self.class.jd jd - _to_jd_for_calc(other)
end
==(other)
Alias for: eql?
===(other) click to toggle source
# File lib/wareki/date.rb, line 233
def ===(other)
  begin
    other.jd == jd or return false
  rescue NoMethodError, NotImplementedError
    return false
  end
  true
end
__set_jd(v) click to toggle source
# File lib/wareki/date.rb, line 125
def __set_jd(v)
  @jd = v
end
_to_jd_for_calc(other) click to toggle source
# File lib/wareki/date.rb, line 250
def _to_jd_for_calc(other)
  other.class.to_s == 'ActiveSupport::Duration' and
    raise NotImplementedError, 'Date calcration with ActiveSupport::Duration currently is not supported. Please use numeric.'
  other.respond_to?(:to_date) and other = other.to_date
  other.respond_to?(:jd) and other = other.jd
  other
end
eql?(other) click to toggle source
# File lib/wareki/date.rb, line 221
def eql?(other)
  begin
    %i[year month day era_year era_name leap_month?].each do |attr|
      other.public_send(attr) == public_send(attr) or return false
    end
  rescue NoMethodError, NotImplementedError
    return false
  end
  true
end
Also aliased as: ==
format(key) click to toggle source
# File lib/wareki/date.rb, line 169
def format(key)
  case key.to_sym
  when :e  then era_name
  when :g  then era_name.to_s == '' ? '' : era_year
  when :G  then era_name.to_s == '' ? '' : Utils.i2z(era_year)
  when :Gk then era_name.to_s == '' ? '' : YaKansuji.to_kan(era_year, :simple)
  when :GK
    if era_name.to_s == ''
      ''
    elsif era_year == 1
      '元'
    else
      YaKansuji.to_kan(era_year, :simple)
    end
  when :o  then year
  when :O  then Utils.i2z(year)
  when :Ok then YaKansuji.to_kan(year, :simple)
  when :i  then imperial_year
  when :I  then Utils.i2z(imperial_year)
  when :Ik then YaKansuji.to_kan(imperial_year, :simple)
  when :s  then month
  when :S  then Utils.i2z(month)
  when :Sk then YaKansuji.to_kan(month, :simple)
  when :SK then Utils.alt_month_name(month)
  when :l  then leap_month? ? "'" : ''
  when :L  then leap_month? ? '’' : ''
  when :Lk then leap_month? ? '閏' : ''
  when :d  then day
  when :D  then Utils.i2z(day)
  when :Dk then YaKansuji.to_kan(day, :simple)
  when :DK
    if month == 1 && !leap_month? && day == 1
      '元'
    elsif day == 1
      '朔'
    elsif day == Utils.last_day_of_month(year, month, leap_month?)
      '晦'
    else
      YaKansuji.to_kan(day, :simple)
    end
  when :m  then "#{format(:s)}#{format(:l)}"
  when :M  then "#{format(:Lk)}#{format(:S)}"
  when :Mk then "#{format(:Lk)}#{format(:Sk)}"
  when :y  then "#{format(:e)}#{format(:g)}"
  when :Y  then "#{format(:e)}#{format(:G)}"
  when :Yk then "#{format(:e)}#{format(:Gk)}"
  when :YK then "#{format(:e)}#{format(:GK)}"
  when :f  then "#{format(:e)}#{format(:g)}年#{format(:s)}#{format(:l)}月#{format(:d)}日"
  when :F  then "#{format(:e)}#{format(:GK)}年#{format(:Lk)}#{format(:Sk)}月#{format(:Dk)}日"
  end
end
imperial_year() click to toggle source
# File lib/wareki/date.rb, line 109
def imperial_year
  @year - IMPERIAL_START_YEAR
end
imperial_year=(v) click to toggle source
# File lib/wareki/date.rb, line 113
def imperial_year=(v)
  @year = v - IMPERIAL_START_YEAR
end
jd() click to toggle source
# File lib/wareki/date.rb, line 140
def jd
  @jd and return @jd

  ['', '西暦', '紀元前'].include?(@era_name) and
    return @jd = ::Date.new(@year, month, day, ::Date::ITALY).jd

  @year >= GREGORIAN_START_YEAR and
    return @jd = ::Date.new(@year, month, day, ::Date::GREGORIAN).jd

  yobj = YEAR_BY_NUM[@year] or
    raise UnsupportedDateRange, "Cannot convert to jd #{inspect}"
  @jd = yobj.month_starts[month_index] + day - 1
end
leap_month=(v) click to toggle source
# File lib/wareki/date.rb, line 121
def leap_month=(v)
  @is_leap_month = v
end
leap_month?() click to toggle source
# File lib/wareki/date.rb, line 117
def leap_month?
  !!@is_leap_month
end
month_index() click to toggle source
# File lib/wareki/date.rb, line 129
def month_index
  return month - 1 if
    ['', '西暦', '紀元前'].include?(@era_name) || @year >= GREGORIAN_START_YEAR

  yobj = YEAR_BY_NUM[@year] or
    raise UnsupportedDateRange, "Cannot get year info of #{inspect}"
  idx = month - 1
  idx += 1 if leap_month? || yobj.leap_month && month > yobj.leap_month
  idx
end
strftime(format_str = '%JF') click to toggle source
# File lib/wareki/date.rb, line 162
def strftime(format_str = '%JF')
  ret = format_str.to_str.gsub(/%J([fFyYegGoOiImMsSlLdD][kK]?)/) { format($1) || $& }
  ret.index('%') or return ret
  d = to_date
  d.respond_to?(:_wareki_strftime_orig) ? d._wareki_strftime_orig(ret) : d.strftime(ret)
end
to_date(start = ::Date::ITALY) click to toggle source
# File lib/wareki/date.rb, line 154
def to_date(start = ::Date::ITALY)
  ::Date.jd(jd, start)
end
to_time() click to toggle source
# File lib/wareki/date.rb, line 158
def to_time
  to_date.to_time
end