Get person's age in Ruby

前端 未结 24 2777
忘了有多久
忘了有多久 2020-11-27 10:32

I\'d like to get a person\'s age from its birthday. now - birthday / 365 doesn\'t work, because some years have 366 days. I came up with the following code:

相关标签:
24条回答
  • 2020-11-27 11:00
    (Date.today.strftime('%Y%m%d').to_i - dob.strftime('%Y%m%d').to_i) / 10000
    
    0 讨论(0)
  • 2020-11-27 11:00
    Time.now.year - self.birthdate.year - (birthdate.to_date.change(:year => Time.now.year) > Time.now.to_date ? 1 : 0)
    
    0 讨论(0)
  • 2020-11-27 11:01

    Use this:

    def age
      now = Time.now.utc.to_date
      now.year - birthday.year - (birthday.to_date.change(:year => now.year) > now ? 1 : 0)
    end
    
    0 讨论(0)
  • 2020-11-27 11:01

    I had to deal with this too, but for months. Became way too complicated. The simplest way I could think of was:

    def month_number(today = Date.today)
      n = 0
      while (dob >> n+1) <= today
        n += 1
      end
      n
    end
    

    You could do the same with 12 months:

    def age(today = Date.today)
      n = 0
      while (dob >> n+12) <= today
        n += 1
      end
      n
    end
    

    This will use Date class to increment the month, which will deal with 28 days and leap year etc.

    0 讨论(0)
  • 2020-11-27 11:02

    Ok what about this:

    def age
      return unless dob
      t = Date.today
      age = t.year - dob.year
      b4bday = t.strftime('%m%d') < dob.strftime('%m%d')
      age - (b4bday ? 1 : 0)
    end
    

    This is assuming we are using rails, calling the age method on a model, and the model has a date database column dob. This is different from other answers because this method uses strings to determine if we are before this year's birthday.

    For example, if dob is 2004/2/28 and today is 2014/2/28, age will be 2014 - 2004 or 10. The floats will be 0228 and 0229. b4bday will be "0228" < "0229" or true. Finally, we will subtract 1 from age and get 9.

    This would be the normal way to compare the two times.

    def age
      return unless dob
      t = Date.today
      age = today.year - dob.year
      b4bday = Date.new(2016, t.month, t.day) < Date.new(2016, dob.month, dob.day)
      age - (b4bday ? 1 : 0)
    end
    

    This works the same, but the b4bday line is too long. The 2016 year is also unnecessary. The string comparison at the beginning was the result.

    You can also do this

    Date::DATE_FORMATS[:md] = '%m%d'
    
    def age
      return unless dob
      t = Date.today
      age = t.year - dob.year
      b4bday = t.to_s(:md) < dob.to_s(:md)
      age - (b4bday ? 1 : 0)
    end
    

    If you aren't using rails, try this

    def age(dob)
      t = Time.now
      age = t.year - dob.year
      b4bday = t.strftime('%m%d') < dob.strftime('%m%d')
      age - (b4bday ? 1 : 0)
    end
    

    0 讨论(0)
  • 2020-11-27 11:04

    This is a conversion of this answer (it's received a lot of votes):

    # convert dates to yyyymmdd format
    today = (Date.current.year * 100 + Date.current.month) * 100 + Date.today.day
    dob = (dob.year * 100 + dob.month) * 100 + dob.day
    # NOTE: could also use `.strftime('%Y%m%d').to_i`
    
    # convert to age in years
    years_old = (today - dob) / 10000
    

    It's definitely unique in its approach but makes perfect sense when you realise what it does:

    today = 20140702 # 2 July 2014
    
    # person born this time last year is a 1 year old
    years = (today - 20130702) / 10000
    
    # person born a year ago tomorrow is still only 0 years old
    years = (today - 20130703) / 10000
    
    # person born today is 0
    years = (today - 20140702) / 10000  # person born today is 0 years old
    
    # person born in a leap year (eg. 1984) comparing with non-leap year
    years = (20140228 - 19840229) / 10000 # 29 - a full year hasn't yet elapsed even though some leap year babies think it has, technically this is the last day of the previous year
    years = (20140301 - 19840229) / 10000 # 30
    
    # person born in a leap year (eg. 1984) comparing with leap year (eg. 2016)
    years = (20160229 - 19840229) / 10000 # 32
    
    0 讨论(0)
提交回复
热议问题