开发者

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

开发者 https://www.devze.com 2022-12-09 21:43 出处:网络
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 开发者_StackOverflow中文版simple to do, b

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 开发者_StackOverflow中文版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.


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.


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.


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


I don't know of such a component, and I don't know how you'd write one; how would it decide which two-digit prefix to use? Picking a single one blindly has certain demonstrated issues.

Depending on your application, you can probably find a reasonable heuristic to pick between 19 and 20 for a prefix, but the problem isn't solvable in general; there's not enough information.


Does doing this really make sense? When should you stop considering 19xx dates? There's no good way to get a 4-digit year from the last 2-digits of the year.

0

精彩评论

暂无评论...
验证码 换一张
取 消