class FlexYear

Represents a flexible year entry:

* 1979 - a specific year
* 1970s and 70s - decades
* mid-70s, early-70s, late-70s - subdecades, dashes optional
* 1972-1975 - a range

All years can be in two or four digit format

Constants

VERSION

Attributes

decade[R]
decades[R]
year_high[R]
year_low[R]

Public Class Methods

new(year_input) click to toggle source
# File lib/flexyear.rb, line 28
def initialize(year_input)
  @year_input = year_input

  if year_input.is_a?(Array)
    parse_year_list(year_input)
  else
    parse_year_string(year_input)
  end
end

Public Instance Methods

decade?() click to toggle source
# File lib/flexyear.rb, line 42
def decade?
  return false unless year_low && year_high
  year_low % 10 == 0 && year_high % 10 == 9
end
parse_decade(yr_low, yr_high) click to toggle source
# File lib/flexyear.rb, line 47
def parse_decade(yr_low, yr_high)
  return if @year_input.is_a?(Array)
  return unless yr_low && yr_high

  same_decade = yr_low.to_s[0,3] == yr_high.to_s[0, 3]
  @decade = "#{yr_low.to_s[0,3]}0s" if same_decade
end
parse_decades(years) click to toggle source
# File lib/flexyear.rb, line 55
def parse_decades(years)
  return unless @year_input.is_a?(Array)

  parsed_decades = years.flat_map { |y| self.class.new(y).decade }
  @decades = parsed_decades
end
to_s() click to toggle source
# File lib/flexyear.rb, line 38
def to_s
  @year_input
end

Private Instance Methods

asterisk_regex() click to toggle source
# File lib/flexyear.rb, line 137
def asterisk_regex
  /(\d+).*\*$/
end
centuryize(year, base_year=nil) click to toggle source
# File lib/flexyear.rb, line 83
def centuryize(year, base_year=nil)
  base = default_base_year(year)
  if base_year
    base = (base_year/100).to_s
  end

  if year.length == 1
    "#{base}0#{year}"
  elsif year.length == 2
    "#{base}#{year}"
  else
    year
  end
end
decade_regex() click to toggle source
# File lib/flexyear.rb, line 141
def decade_regex
  /(\d+).*s$/
end
default_base_year(year) click to toggle source
# File lib/flexyear.rb, line 98
def default_base_year(year)
  current_year = Date.today.year.to_s
  if year.to_i < current_year[-2..-1].to_i
    "20" # 21st century
  else
    "19" # 20th century
  end
end
parse_year(year_string) click to toggle source
# File lib/flexyear.rb, line 107
def parse_year(year_string)
  low, high = RangeParser.parse(year_string)

  if year_string =~ range_regex && $1 && $2
    @year_low = centuryize($1).to_i
    @year_low, @year_high = [@year_low, centuryize($2, @year_low).to_i].sort
  else
    if year_string =~ decade_regex
      @base_year = centuryize($1).to_i
    elsif year_string =~ asterisk_regex
      @base_year = centuryize($1).to_i * 10
    elsif year_string =~ starts_with_word_regex
      @base_year = centuryize($1).to_i
    else
      @base_year = centuryize(year_string.gsub(/\D+/,'')).to_i
    end

    if @base_year > 9999
      raise InvalidYearError, "Please use a four digit year."
    end

    @year_low = @base_year + low unless low.nil?
    @year_high = @base_year + high unless high.nil?
  end
end
parse_year_list(years) click to toggle source
# File lib/flexyear.rb, line 64
def parse_year_list(years)
  all_years = years.flat_map do |y|
    year = self.class.new(y)
    [year.year_low, year.year_high]
  end

  flat_years = all_years.compact.uniq

  @year_low = flat_years.min
  @year_high = flat_years.max

  parse_decades(years)
end
parse_year_string(year_string) click to toggle source
# File lib/flexyear.rb, line 78
def parse_year_string(year_string)
  parse_year(year_string.to_s.strip)
  parse_decade(@year_low, @year_high)
end
range_regex() click to toggle source
# File lib/flexyear.rb, line 133
def range_regex
  /(\d+)\s*-\s*(\d+)/
end
starts_with_word_regex() click to toggle source
# File lib/flexyear.rb, line 145
def starts_with_word_regex
  /^\w+\s+(\d+)/
end