Ruby on rails 获取person';红宝石时代

Ruby on rails 获取person';红宝石时代,ruby-on-rails,ruby,Ruby On Rails,Ruby,我想从一个人的生日得到他的年龄现在-生日/365不起作用,因为有些年份有366天。我想出了以下代码: now = Date.today year = now.year - birth_date.year if (date+year.year) > now year = year - 1 end 有没有一种更像红宝石的方法来计算年龄?使用这个: def age now = Time.now.utc.to_date now.year - birthday.year - (bir

我想从一个人的生日得到他的年龄<代码>现在-生日/365不起作用,因为有些年份有366天。我想出了以下代码:

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

if (date+year.year) > now
  year = year - 1
end
有没有一种更像红宝石的方法来计算年龄?

使用这个:

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

我发现这个解决方案很好地工作,并且可以为其他人阅读:

    age = Date.today.year - birthday.year
    age -= 1 if Date.today < birthday + age.years #for days before birthday
age=Date.today.year-birth.year
年龄-=1,如果Date.today<生日+年龄.years#为生日前几天

简单,你不必担心如何处理闰年之类的问题。

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

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

您将得到一个分数结果,因此可以使用
to_i
将结果转换为整数。这是一个更好的解决方案,因为它正确地将日期差异视为自事件发生以来以天(或在相关时间类中以秒为单位)度量的时间段。然后简单除以一年中的天数,就可以得到年龄。以年为单位计算年龄时,只要您保留原始的出生日期值,就不需要为闰年预留任何余量。

以下内容似乎有效(但如果选中,我将不胜感激)

age=now.year-bday.year
年龄-=1如果现在到a[7]
我知道我来晚了,但当我试图计算出闰年2月29日出生的人的年龄时,公认的答案会大打折扣。这是因为调用
birth.to_date.change(:year=>now.year)
会创建无效的日期

我使用了以下代码:

需要“日期”
def年龄(dob)
现在=Time.now.utc.to_日期
now.year-dob.year-((now.month>dob.month | | |(now.month==dob.month&&now.day>=dob.day))?0:1)
结束

RubyonRails(ActiveSupport)中的一行程序。处理闰年、闰秒等

def age(birthday)
  (Time.now.to_s(:number).to_i - birthday.to_time.to_s(:number).to_i)/10e9.to_i
end
从这里开始的逻辑-

假设两个日期都在同一时区,如果不在这两个日期上调用
utc()
之前的

我喜欢这个:

now = Date.current
age = now.year - dob.year
age -= 1 if now.yday < dob.yday
now=Date.current
年龄=现在.年-出生日期.年
年龄-=1如果now.yday
我也不得不处理这件事,但已经处理了好几个月了。变得太复杂了。我能想到的最简单的方法是:

def month_number(today = Date.today)
  n = 0
  while (dob >> n+1) <= today
    n += 1
  end
  n
end
def月号(今天=日期。今天)
n=0
虽然(dob>>n+1)>n+12)是最好的,但还是向上投票吧


我喜欢@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
def年龄(dob)
现在=今天
now.year-dob.year-(now.strftime(“%m%d”)
考虑闰年(并假设存在activesupport):

years\u自
起将正确修改日期,以考虑非闰年(生日为
02-29
)。

我的建议:

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

诀窍在于,带时间的减号操作返回秒,因为RubyonRails被标记,所以gem覆盖内置的Rails并提供可用于确定年龄的值。闰年在年份部分处理得很好,但请注意,2月29日确实会对天数部分产生影响,如果需要了解详细程度,则需要了解。此外,如果您不喜欢dotiw以文字形式更改距离和时间的格式,请使用:vague选项还原为原始格式

将dotiw添加到文件:

gem 'dotiw'
在命令行上:

bundle
在适当的模型中包含DateHelper,以访问单词中的时间距离和单词中的时间距离。在本例中,模型为“用户”,生日字段为“生日”

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

u = User.new("birthday(1i)" => "2011", "birthday(2i)" => "10", "birthday(3i)" => "23")
u.age
> BirthDate.new(Date.parse('1988-02-29')).time_ago_in_years
 => 31 
这是(获得了很多选票)的转换:

它的方法绝对是独一无二的,但当你意识到它的作用时,它是非常有意义的:

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

如果你不在乎一两天,这将是一个简短的自我嘲讽

(Time.now - Time.gm(1986, 1, 27).to_i).year - 1970
好的,这个怎么样:

def年龄
除非dob,否则返回
t=今天的日期
年龄=t年-出生日期年
b4bday=t.strftime(“%m%d”)
这是假设我们使用rails,在模型上调用
age
方法,并且模型有一个日期数据库列
dob
。这与其他答案不同,因为此方法使用字符串来确定我们是否在今年的生日之前

例如,如果
dob
是2004/2/28,而
今天的
是2014/2/28,
age
将是
2014-2004
10
。浮动将是
0228
0229
<代码>b4bday
将是
“0228”
。最后,我们将从
age
中减去
1
,得到
9

这是比较这两次的正常方法

def age
  return unless dob
  t = Date.today
  age = today.year - dob.year
  b4bday = Date.new(2016, t.month, t.day) < Date.new(2016, dob.month, dob.day)
  age - (b4bday ? 1 : 0)
end
如果您没有使用rails,请尝试以下方法

def age(dob)
  t = Time.now
  age = t.year - dob.year
  b4bday = t.strftime('%m%d') < dob.strftime('%m%d')
  age - (b4bday ? 1 : 0)
end
def年龄(dob)
t=时间。现在
年龄=t年-出生日期年
b4bday=t.strftime(“%m%d”)

我认为最好不要计算月份,因为您可以使用
Time.zone.now.yday
获得一年中的确切日期

def age
  years  = Time.zone.now.year - birthday.year
  y_days = Time.zone.now.yday - birthday.yday

  y_days < 0 ? years - 1 : years
end
def年龄
年份=Time.zone.now.year-生日.year
y_days=Time.zone.now.yday-生日.yday
y_天<0天?年-1:年
结束

这是我的解决方案,它还允许计算特定日期的年龄:

def age on = Date.today
  (_ = on.year - birthday.year) - (on < birthday.since(_.years) ? 1 : 0)
end
def age on=Date.today
(年月日-生日年)-(年月日)1:0
结束

提出了Rails的一个变体


我相信这在功能上等同于@philnash的答案,但我更容易理解

class BirthDate
  def initialize(birth_date)
    @birth_date = birth_date
    @now = Time.now.utc.to_date
  end

  def time_ago_in_years
    if today_is_before_birthday_in_same_year?
      age_based_on_years - 1
    else
      age_based_on_years
    end
  end

  private

  def age_based_on_years
    @now.year - @birth_date.year
  end

  def today_is_before_birthday_in_same_year?
    (@now.month < @birth_date.month) || ((@now.month == @birth_date.month) && (@now.day < @birth_date.day))
  end
end

DateHelper只能用于获取年份

puts time_ago_in_words '1999-08-22'
将近20年

这需要Rails(针对age.years),但如果您执行类似于
Date.today的操作,则可以不需要Rails。
(Time.now - Time.gm(1986, 1, 27).to_i).year - 1970
def age
  return unless dob
  t = Date.today
  age = today.year - dob.year
  b4bday = Date.new(2016, t.month, t.day) < Date.new(2016, dob.month, dob.day)
  age - (b4bday ? 1 : 0)
end
Date::DATE_FORMATS[:md] = '%m%d'

def age
  return unless dob
  t = Date.today
  age = t.year - dob.year
  b4bday = t.to_s(:md) < dob.to_s(:md)
  age - (b4bday ? 1 : 0)
end
def age(dob)
  t = Time.now
  age = t.year - dob.year
  b4bday = t.strftime('%m%d') < dob.strftime('%m%d')
  age - (b4bday ? 1 : 0)
end
def age
  years  = Time.zone.now.year - birthday.year
  y_days = Time.zone.now.yday - birthday.yday

  y_days < 0 ? years - 1 : years
end
def age on = Date.today
  (_ = on.year - birthday.year) - (on < birthday.since(_.years) ? 1 : 0)
end
def age(dob)
    now = Date.today
    age = now.year - dob.year
    age -= 1 if dob > now.years_ago(age)
    age
end
class BirthDate
  def initialize(birth_date)
    @birth_date = birth_date
    @now = Time.now.utc.to_date
  end

  def time_ago_in_years
    if today_is_before_birthday_in_same_year?
      age_based_on_years - 1
    else
      age_based_on_years
    end
  end

  private

  def age_based_on_years
    @now.year - @birth_date.year
  end

  def today_is_before_birthday_in_same_year?
    (@now.month < @birth_date.month) || ((@now.month == @birth_date.month) && (@now.day < @birth_date.day))
  end
end
> BirthDate.new(Date.parse('1988-02-29')).time_ago_in_years
 => 31 
puts time_ago_in_words '1999-08-22'
  def computed_age
    if birth_date.present?
      current_time.year - birth_date.year - (age_by_bday || check_if_newborn ? 0 : 1)
    else
      age.presence || 0
    end
  end


  private

  def current_time
    Time.now.utc.to_date
  end

  def age_by_bday
    current_time.month > birth_date.month
  end

  def check_if_newborn
    (current_time.month == birth_date.month && current_time.day >= birth_date.day)
  end```