在Ruby中获取人的年龄
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/819263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get person's age in Ruby
提问by Mantas
I'd like to get a person's age from its birthday. now - birthday / 365doesn't work, because some years have 366 days. I came up with the following code:
我想从一个人的生日得到一个人的年龄。now - birthday / 365不起作用,因为有些年份有 366 天。我想出了以下代码:
now = Date.today
year = now.year - birth_date.year
if (date+year.year) > now
year = year - 1
end
Is there a more Ruby'ish way to calculate age?
有没有更像 Ruby'ish 的方法来计算年龄?
回答by philnash
I know I'm late to the party here, but the accepted answer will break horribly when trying to work out the age of someone born on the 29th February on a leap year. This is because the call to birthday.to_date.change(:year => now.year)creates an invalid date.
我知道我在这里参加聚会迟到了,但是当试图计算出闰年 2 月 29 日出生的人的年龄时,接受的答案会非常糟糕。这是因为调用birthday.to_date.change(:year => now.year)创建了一个无效的日期。
I used the following code instead:
我改用以下代码:
require 'date'
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
回答by PJ.
I've found this solution to work well and be readable for other people:
我发现这个解决方案运行良好并且对其他人可读:
age = Date.today.year - birthday.year
age -= 1 if Date.today < birthday + age.years #for days before birthday
Easy and you don't need to worry about handling leap year and such.
简单,您无需担心处理闰年等问题。
回答by Sadegh
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
回答by Vikrant Chaudhary
One liner in Ruby on Rails (ActiveSupport). Handles leap years, leap seconds and all.
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
Logic from here - Calculate age in C#
从这里开始的逻辑 -在 C# 中计算年龄
Assuming both dates are in same timezone, if not call utc()before to_s()on both.
假设两个日期都在同一个时区,如果没有在两者utc()之前调用to_s()。
回答by pguardiario
(Date.today.strftime('%Y%m%d').to_i - dob.strftime('%Y%m%d').to_i) / 10000
回答by Bob Aman
The answers so far are kinda weird. Your original attempt was pretty close to the right way to do this:
到目前为止的答案有点奇怪。您最初的尝试非常接近正确的方法:
birthday = DateTime.new(1900, 1, 1)
age = (DateTime.now - birthday) / 365.25 # or (1.year / 1.day)
You will get a fractional result, so feel free to convert the result to an integer with to_i. This is a better solution because it correctly treats the date difference as a time period measured in days (or seconds in the case of the related Time class) since the event. Then a simple division by the number of days in a year gives you the age. When calculating age in years this way, as long as you retain the original DOB value, no allowance needs to be made for leap years.
您将得到一个小数结果,因此可以随意将结果转换为整数to_i。这是一个更好的解决方案,因为它正确地将日期差异视为自事件发生以来以天(或在相关 Time 类的情况下为秒)度量的时间段。然后简单地除以一年中的天数就可以得出年龄。以这种方式计算年龄时,只要保留原始 DOB 值,就不需要考虑闰年。
回答by jlebrijo
My suggestion:
我的建议:
def age(birthday)
((Time.now - birthday.to_time)/(60*60*24*365)).floor
end
The trick is that the minus operation with Time returns seconds
诀窍是 Time 的减号操作返回秒
回答by artm
This answeris the best, upvote it instead.
这个答案是最好的,请点赞。
I like @philnash's solution, but the conditional could be compacter. What that boolean expression does is comparing [month, day] pairs using lexicographic order, so one could just use ruby's string comparison instead:
我喜欢@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
回答by br3nt
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
回答by tpalm
I like this one:
我喜欢这个:
now = Date.current
age = now.year - dob.year
age -= 1 if now.yday < dob.yday

