在Ruby中获取人的年龄

Man*_*tas 122 ruby ruby-on-rails

我想从一个人的生日那里得到一个人的年龄.now - birthday / 365不起作用,因为有些年份有366天.我想出了以下代码:

now = Date.today
year = now.year - birth_date.year

if (date+year.year) > now
  year = year - 1
end
Run Code Online (Sandbox Code Playgroud)

是否有更多Ruby的计​​算年龄的方法?

phi*_*ash 405

我知道我在这里参加派对的时间已经很晚了,但是当我试图计算出闰年2月29日出生的人的年龄时,接受的答案会非常糟糕.这是因为调用birthday.to_date.change(:year => now.year)创建了无效日期.

我使用以下代码(在Rails项目中):

def age(dob)
  now = Time.now.utc.to_date
  now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
Run Code Online (Sandbox Code Playgroud)

  • 使用此,而不是无法处理闰年的经过检查的 (4认同)
  • @VladoCingel,如果当前月份在生日月份之前并且当前日期在生日之前,例如,如果今天是 7 月 23 日,生日是 12 月 21 日,这将返回错误的结果。 (3认同)
  • @alex0112因为那个公认令人困惑的条件的结果(0或1)是从现在和生日之间的年差中减去的。目的是找出这个人今年是否过生日,如果没有,则比年份差小1岁。 (2认同)
  • @andrej now = Date.today有效,但请注意它不处理Timezone问题.在Rails Date.today中,返回基于系统时区的日期.ActiveRecord根据您配置的Apps时区返回时间.如果系统时区与您的应用程序时区不同,您实际上将比较来自两个不同时区的时间,这不是非常准确. (2认同)

PJ.*_*PJ. 49

我发现这个解决方案运行良好,并且可供其他人阅读:

    age = Date.today.year - birthday.year
    age -= 1 if Date.today < birthday + age.years #for days before birthday
Run Code Online (Sandbox Code Playgroud)

容易,您不必担心处理闰年等.

  • 这需要滑轨(用于age.years),但可以作出不要求Rails的,如果你不喜欢的东西`Date.today.month <birthday.month或Date.today.month == birthday.month && Date.today.mday <birthday.mday`. (3认同)
  • @sigvei - 这是一个功能,而不是一个错误;)在大多数国家,包括美国,如果你是一个跳跃的婴儿,第28届在法律上被视为你的生日非闰年.这个人确实会被认为是10. (2认同)

Sad*_*egh 33

用这个:

def age
  now = Time.now.utc.to_date
  now.year - birthday.year - (birthday.to_date.change(:year => now.year) > now ? 1 : 0)
end
Run Code Online (Sandbox Code Playgroud)

  • 如果birthday.to_date是闰年而当前年份不是闰年,则会中断.不是很大的事,但它一直在给我带来麻烦. (41认同)
  • 选择[philnash的答案](http://stackoverflow.com/a/2357790/162793)的另一个原因是,它适用于普通的旧Ruby,而可接受的答案仅适用于`rails / activesupport`。 (2认同)

Vik*_*ary 16

Ruby on Rails中的一个内核(ActiveSupport).处理闰年,闰秒等等.

def age(birthday)
  (Time.now.to_s(:number).to_i - birthday.to_time.to_s(:number).to_i)/10e9.to_i
end
Run Code Online (Sandbox Code Playgroud)

逻辑从这里开始 - 用C#计算年龄

假设两个日期都在同一时区,如果utc()之前没有调用两个日期to_s().


pgu*_*rio 9

(Date.today.strftime('%Y%m%d').to_i - dob.strftime('%Y%m%d').to_i) / 10000
Run Code Online (Sandbox Code Playgroud)


Bob*_*man 6

到目前为止的答案有点奇怪.您最初的尝试非常接近正确的方法:

birthday = DateTime.new(1900, 1, 1)
age = (DateTime.now - birthday) / 365.25 # or (1.year / 1.day)
Run Code Online (Sandbox Code Playgroud)

您将得到一个小数结果,所以随意将结果转换为整数to_i.这是一个更好的解决方案,因为它正确地将日期差异视为自事件以来以天(或相关时间类的情况下为秒)测量的时间段.然后根据一年中的天数进行简单划分即可得出年龄.以这种方式计算年龄时,只要保留原始DOB值,就不需要考虑闰年.


jle*_*ijo 6

我的建议:

def age(birthday)
    ((Time.now - birthday.to_time)/(60*60*24*365)).floor
end
Run Code Online (Sandbox Code Playgroud)

诀窍是使用Time的减号操作返回秒


art*_*rtm 5

这个答案是最好的,请赞成。


我喜欢@philnash的解决方案,但条件可以更紧凑。布尔表达式的作用是使用字典顺序比较[month,day]对,因此可以只使用ruby的字符串比较:

def age(dob)
  now = Date.today
  now.year - dob.year - (now.strftime('%m%d') < dob.strftime('%m%d') ? 1 : 0)
end
Run Code Online (Sandbox Code Playgroud)