Get person's age in Ruby

前端 未结 24 2776
忘了有多久
忘了有多久 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 10:46

    Here's my solution which also allows calculating the age at a specific date:

    def age on = Date.today
      (_ = on.year - birthday.year) - (on < birthday.since(_.years) ? 1 : 0)
    end
    
    0 讨论(0)
  • 2020-11-27 10:47
      def birthday(user)
        today = Date.today
        new = user.birthday.to_date.change(:year => today.year)
        user = user.birthday
        if Date.civil_to_jd(today.year, today.month, today.day) >= Date.civil_to_jd(new.year, new.month, new.day)
          age = today.year - user.year
        else
          age = (today.year - user.year) -1
        end
        age
      end
    
    0 讨论(0)
  • 2020-11-27 10:49

    If you don't care about a day or two, this would be shorter and pretty self-explanitory.

    (Time.now - Time.gm(1986, 1, 27).to_i).year - 1970
    
    0 讨论(0)
  • 2020-11-27 10:50

    One liner in Ruby on Rails (ActiveSupport). Handles leap years, leap seconds and all.

    def age(birthday)
      (Time.now.to_s(:number).to_i - birthday.to_time.to_s(:number).to_i)/10e9.to_i
    end
    

    Logic from here - Calculate age in C#

    Assuming both dates are in same timezone, if not call utc() before to_s() on both.

    0 讨论(0)
  • The following seems to work (but I'd appreciate it if it was checked).

    age = now.year - bday.year
    age -= 1 if now.to_a[7] < bday.to_a[7]
    
    0 讨论(0)
  • 2020-11-27 10:51

    Because Ruby on Rails is tagged, the dotiw gem overrides the Rails built-in distance_of_times_in_words and provides distance_of_times_in_words_hash which can be used to determine the age. Leap years are handled fine for the years portion although be aware that Feb 29 does have an effect on the days portion that warrants understanding if that level of detail is needed. Also, if you don't like how dotiw changes the format of distance_of_time_in_words, use the :vague option to revert to the original format.

    Add dotiw to the Gemfile:

    gem 'dotiw'
    

    On the command line:

    bundle
    

    Include the DateHelper in the appropriate model to gain access to distance_of_time_in_words and distance_of_time_in_words_hash. In this example the model is 'User' and the birthday field is 'birthday.

    class User < ActiveRecord::Base
      include ActionView::Helpers::DateHelper
    

    Add this method to that same model.

    def age
      return nil if self.birthday.nil?
      date_today = Date.today
      age = distance_of_time_in_words_hash(date_today, self.birthday).fetch("years", 0)
      age *= -1 if self.birthday > date_today
      return age
    end
    

    Usage:

    u = User.new("birthday(1i)" => "2011", "birthday(2i)" => "10", "birthday(3i)" => "23")
    u.age
    
    0 讨论(0)
提交回复
热议问题