Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert two-digit year to four-digit year in Ruby

Tags:

date

time

ruby

I have strings like "84", "03" etc. that I want to convert to Date objects, but Date.new only takes the expanded 4-digit year as a parameter. I know it's simple to do, but I don't want to reinvent this wheel. Is there something that does this already? Either in standard Ruby or in ActiveSupport.

like image 220
agentofuser Avatar asked Oct 28 '09 19:10

agentofuser


3 Answers

Pick a cutoff date.

if year < cutoff, then year4 = "20" + year
else year4 = "19" + year

Also, fix the cause of the two digit year, or else your system won't be Y2K+cutoff compliant.

like image 126
Steven Avatar answered Oct 08 '22 18:10

Steven


Most 2 digit years are in the past, so a good cutoff to use is 30. For example, if someone types '66, they most likely mean 1966. In fact, this is also the cutoff that Excel uses when a two digit date is passed to a date cell.

I had an application that accepted tab delimited files from excel spreadsheets, and they often came with two-digit years. I wrote this ActiveRecord monkey patch to allow ActiveRecord to handle the two digit years for date fields:

class ActiveRecord::ConnectionAdapters::Column
  class << self
    protected
    # If a year comes in with two digits, let's try to guess whether it's in the
    # 20th or 21st century.  Typically, Ruby pivots this decision around the
    # year '69, but this is a bad guess.  Since most of our dates will arrive in
    # two digit format because of an Excel import, we should use the same pivot
    # value that Excel uses.  Excel pivots the decision around the year '30
    # which seems to be a better guess anyway.
    def new_date_with_two_digit_year_support(year, mon, mday)
      year += 2000 if (0..29).include? year
      year += 1900 if (30..99).include? year
      new_date_without_two_digit_year_support(year, mon, mday)
    end
    alias_method_chain :new_date, :two_digit_year_support
  end
end

This isn't exactly as generic as what the question asked for, but hopefully, it helps.

like image 31
Ryan McGeary Avatar answered Oct 08 '22 20:10

Ryan McGeary


If you want to convert 2 to 4 for future dates (like formatting a credit card exp date) you could try:

$expYear  = 12

if (strlen($expYear) == 2) {
    $expYear = substr(Date("Y"),0,2) . $expYear;
}

This will be slightly more future proof as it always gets the current year However, if we are in the 95th+ year of the century.. it will still cause problems c'est la vie

like image 43
DssTrainer Avatar answered Oct 08 '22 20:10

DssTrainer