

Task

Convert a given date from the   Gregorian calendar   to the   Discordian calendar.




require 'date'
 
class DiscordianDate
  SEASON_NAMES = ["Chaos","Discord","Confusion","Bureaucracy","The Aftermath"]
  DAY_NAMES = ["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange"]
  YEAR_OFFSET = 1166
  DAYS_PER_SEASON = 73
  DAYS_PER_WEEK = 5
  ST_TIBS_DAY_OF_YEAR = 60
 
  def initialize(year, month, day)
    gregorian_date = Date.new(year, month, day)
    @day_of_year = gregorian_date.yday
 
    @st_tibs = false
    if gregorian_date.leap?
      if @day_of_year == ST_TIBS_DAY_OF_YEAR
        @st_tibs = true
      elsif @day_of_year > ST_TIBS_DAY_OF_YEAR
        @day_of_year -= 1
      end
    end
 
    @season, @day = (@day_of_year-1).divmod(DAYS_PER_SEASON)
    @day += 1     #←              ↑ fixes of-by-one error (only visible at season changes)
    @year = gregorian_date.year + YEAR_OFFSET
  end
  attr_reader :year, :day
 
  def season
    SEASON_NAMES[@season]
  end
 
  def weekday
    if @st_tibs
      "St. Tib's Day"
    else
      DAY_NAMES[(@day_of_year - 1) % DAYS_PER_WEEK]
    end
  end
 
  def to_s
    %Q{#{@st_tibs ? "St. Tib's Day" : "%s, %s %d" % [weekday, season, day]}, #{year} YOLD}
  end
end