# frozen_string_literal: true
require 'date'
class Calendarian
class << self
private :new
def [] src
return nil if src == nil
return src if self === src
value = case src
when Date
self.date_to_value src
when Time
self.date_to_value src.to_date
when String
date = Date::parse src
self.date_to_value date
when Integer
src
else
raise TypeError, "Invalid date: #{ src.inspect }", caller
end
return nil if value == nil
@values ||= {}
@values[value] ||= new value
@values[value]
end
end
attr_reader :value
def initialize value
@value = value
end
include Comparable
def <=> other
return nil unless self.class === other
@value <=> other.value
end
end
class Year < Calendarian
class << self
protected def date_to_value date
date.year
end
end
alias :year :value
def - num
self.class[@value - num]
end
def to_s
" #{ @value } год"
end
def query_params
"year=#{ @value }"
end
end
class Month < Calendarian
class << self
protected def date_to_value date
date.month
end
end
alias :month :value
NAMES = {
1 => 'Январь',
2 => 'Февраль',
3 => 'Март',
4 => 'Апрель',
5 => 'Май',
6 => 'Июнь',
7 => 'Июль',
8 => 'Август',
9 => 'Сентябрь',
10 => 'Октябрь',
11 => 'Ноябрь',
12 => 'Декабрь'
}
def to_s
" #{ NAMES[@value] }"
end
def query_params
"month=#{ @value }"
end
end
class Day < Calendarian
class << self
protected def date_to_value date
date.day
end
end
alias :day :value
def to_s
" #{ @value }"
end
def query_params
"day=#{ @value }"
end
end
class Winter < Calendarian
class << self
protected def date_to_value date
month = date.month
if month <= 4
date.year
elsif month >= 10
date.year + 1
else
nil
end
end
end
alias :winter :value
def to_s
" Зима #{ @value - 1 }–#{ @value }"
end
def query_params
"d1=#{ @value - 1 }-10-01&d2=#{ @value }-04-30"
end
end