在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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:12:22  来源:igfitidea点击:

Get person's age in Ruby

ruby-on-railsruby

提问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