module DateAsString

Public Class Methods

guess_century(year, cutoff=20) click to toggle source
# File lib/date_as_string.rb, line 6
def self.guess_century(year, cutoff=20)
  century = get_century_from_year_range(year, cutoff)

  century.present? ? century : raise_century_error
end
included(base) click to toggle source
# File lib/date_as_string.rb, line 12
def self.included(base)
  base.send(:extend, DateAsString::ClassMethods)
end
parse_date(date) click to toggle source
# File lib/date_as_string.rb, line 16
def self.parse_date(date)
  date.respond_to?(:strftime) ? date.strftime('%m/%d/%Y') : nil
end
parse_string(date_string) click to toggle source
# File lib/date_as_string.rb, line 20
def self.parse_string(date_string)
  begin
    case
    when t_regex.match(date_string)
      date_for_t_match(date_string)
    when mmddyy_regex.match(date_string)
      date_for_mmddyy_match(date_string)
    when mmddyy_regex(with_slashes: true).match(date_string)
      date_for_mmddyy_match(date_string, with_slashes: true)
    when mmddyyyy_regex.match(date_string)
      date_for_mmddyyyy_match(date_string)
    when mmddyyyy_regex(with_slashes: true).match(date_string)
      date_for_mmddyyyy_match(date_string, with_slashes: true)
    else
      nil
    end
  rescue
    nil
  end
end

Private Class Methods

date_for_mmddyy_match(date_string, options={}) click to toggle source
# File lib/date_as_string.rb, line 191
def self.date_for_mmddyy_match(date_string, options={})
  slashy_regex = options.fetch(:with_slashes, false)
  month, day, year = nil, nil, nil

  mmddyy_regex(with_slashes: slashy_regex).match(date_string) do |match_data|
    month = match_data[:month] ? match_data[:month] : date_string[0..1]
    day = match_data[:day] ? match_data[:day] : date_string[2..3]
    year = match_data[:year] ? match_data[:year] : date_string[4..5]

    century = DateAsString.guess_century(year.to_i)

    Date.civil(century, month.to_i, day.to_i)
  end
end
date_for_mmddyyyy_match(date_string, options={}) click to toggle source
# File lib/date_as_string.rb, line 206
def self.date_for_mmddyyyy_match(date_string, options={})
  slashy_regex = options.fetch(:with_slashes, false)
  month, day, year = nil, nil, nil

  mmddyyyy_regex(with_slashes: slashy_regex).match(date_string) do |match_data|
    month = match_data[:month] ? match_data[:month] : date_string[0..1]
    day = match_data[:day] ? match_data[:day] : date_string[2..3]
    year = match_data[:year] ? match_data[:year] : date_string[4..5]

    Date.civil(year.to_i, month.to_i, day.to_i)
  end
end
date_for_t_match(date_string) click to toggle source

matches:

e.g.)
  t   => Date.today
  t+7 => Date.today + 1.week
  t-1 => Date.today - 1.day
# File lib/date_as_string.rb, line 181
def self.date_for_t_match(date_string)
  today = Time&.zone&.today || Date.today

  t_regex.match(date_string) do |match_data|
    operator, days_count = *[match_data[:operator], match_data[:days_count]]

    operator ? today.send(operator, days_count.to_i) : today
  end
end
get_century_from_year_range(year, cutoff=20) click to toggle source
# File lib/date_as_string.rb, line 124
def self.get_century_from_year_range(year, cutoff=20)
  year_range(cutoff).detect { |temp_year| temp_year % 100 == year }
end
mmddyy_regex(options={}) click to toggle source

Allow MMDDYY or MM/DD/YY

# File lib/date_as_string.rb, line 137
def self.mmddyy_regex(options={})
  with_slashes = options.fetch(:with_slashes, false)

  slash_str = with_slashes ? '/' : nil
  month_str = '(?<month>[0-1]?\d)'
  day_str = '(?<day>[0-3]?\d)'
  year_str =  '(?<year>\d{2})'

  date_tup = [month_str, day_str, year_str]
  slashes = [slash_str]*2

  inner_regex = date_tup.zip(slashes)
                        .flatten
                        .compact
                        .join

  /^#{inner_regex}$/
end
mmddyyyy_regex(options={}) click to toggle source

Allow MMDDYYYY or MM/DD/YYYY

# File lib/date_as_string.rb, line 157
def self.mmddyyyy_regex(options={})
  with_slashes = options.fetch(:with_slashes, false)

  slash_str = with_slashes ? '/' : nil
  month_str = '(?<month>[0-1]?\d)'
  day_str = '(?<day>[0-3]?\d)'
  year_str =  '(?<year>\d{4})'

  date_tup = [month_str, day_str, year_str]
  slashes = [slash_str]*2

  inner_regex = date_tup.zip(slashes)
                        .flatten
                        .compact
                        .join

  /^#{inner_regex}$/
end
raise_century_error() click to toggle source
# File lib/date_as_string.rb, line 128
def self.raise_century_error
  raise RangeError.new('Error converting year...')
end
t_regex() click to toggle source
# File lib/date_as_string.rb, line 132
def self.t_regex
  /^[tT]((?<operator>[\-\+])(?<days_count>\d+))?$/
end
year_range(cutoff) click to toggle source
# File lib/date_as_string.rb, line 115
def self.year_range(cutoff)
  current_year = Time&.zone&.today&.year || Date.today.year

  range_start = current_year - (99 - cutoff)
  range_end = current_year + cutoff

  range_start..range_end
end