Получить возраст человека в рубине - PullRequest
120 голосов
/ 04 мая 2009

Я бы хотел узнать возраст человека с дня рождения. now - birthday / 365 не работает, потому что у некоторых лет есть 366 дней. Я придумал следующий код:

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

if (date+year.year) > now
  year = year - 1
end

Есть ли более рубиновый способ подсчета возраста?

Ответы [ 23 ]

399 голосов
/ 01 марта 2010

Я знаю, что опаздываю на вечеринку здесь, но принятый ответ ужасно сломается, если попытаться определить возраст человека, рожденного 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
49 голосов
/ 04 мая 2009

Я нашел, что это решение хорошо работает и доступно для чтения другим людям:

    age = Date.today.year - birthday.year
    age -= 1 if Date.today < birthday + age.years #for days before birthday

Легко, и вам не нужно беспокоиться об обработке високосного года и тому подобное.

33 голосов
/ 04 мая 2009

Используйте это:

def age
  now = Time.now.utc.to_date
  now.year - birthday.year - (birthday.to_date.change(:year => now.year) > now ? 1 : 0)
end
16 голосов
/ 28 сентября 2011

Один вкладыш в 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

Логика отсюда - Рассчитать возраст в C #

Предполагая, что обе даты находятся в одном часовом поясе, если нет, позвоните utc() до to_s() в обе.

9 голосов
/ 11 июля 2012
(Date.today.strftime('%Y%m%d').to_i - dob.strftime('%Y%m%d').to_i) / 10000
6 голосов
/ 18 октября 2013

Мое предложение:

def age(birthday)
    ((Time.now - birthday.to_time)/(60*60*24*365)).floor
end

Хитрость в том, что операция минус с временем возвращает секунды

6 голосов
/ 04 мая 2009

Ответы пока что странные. Ваша первоначальная попытка была довольно близка к правильному способу сделать это:

birthday = DateTime.new(1900, 1, 1)
age = (DateTime.now - birthday) / 365.25 # or (1.year / 1.day)

Вы получите дробный результат, поэтому не стесняйтесь конвертировать результат в целое число с to_i. Это лучшее решение, поскольку оно правильно обрабатывает разницу дат как период времени, измеренный в днях (или секундах в случае соответствующего класса времени) с момента события. Тогда простое деление на количество дней в году дает вам возраст. Таким образом, при расчете возраста в годах, при условии, что вы сохраняете исходное значение DOB, не нужно делать поправку на високосные годы.

4 голосов
/ 03 февраля 2012

Мне нравится этот:

now = Date.current
age = now.year - dob.year
age -= 1 if now.yday < dob.yday
4 голосов
/ 23 февраля 2013

Этот ответ лучший, вместо этого проголосуйте.


Мне нравится решение @ philnash, но условное может быть компактным. То, что делает это логическое выражение, сравнивает пары [месяц, день], используя лексикографический порядок , так что вместо этого можно использовать сравнение строк ruby:

def age(dob)
  now = Date.today
  now.year - dob.year - (now.strftime('%m%d') < dob.strftime('%m%d') ? 1 : 0)
end
2 голосов
/ 02 июля 2014

Это преобразование этого ответа (получено много голосов):

# 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

Он определенно уникален в своем подходе, но имеет смысл, когда понимаешь, что он делает:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...