如何计算Ruby中给定日期以来已经过去了多少年?

Posted

技术标签:

【中文标题】如何计算Ruby中给定日期以来已经过去了多少年?【英文标题】:How to calculate how many years passed since a given date in Ruby? 【发布时间】:2010-12-26 14:55:03 【问题描述】:

这个问题是针对其他语言的,所以这里是针对 Ruby 的一个问题。

如何计算从给定日期过去的完整年数?正如您可能已经猜到的那样,这是自动计算人的年龄。最接近的是distance_of_time_in_words Rails helper,所以下面的模板

Jack is <%= distance_of_time_in_words (Time.now, Time.local(1950,03,22)) %> old.

产量

Jack is over 59 years old.

但我需要更精确的函数,只产生数字。有吗?

如果为此存在某种 Ruby on Rails 辅助函数,这没关系,尽管纯 Ruby 解决方案会更好。

编辑:问题的要点是需要一个非近似解决方案。三月 2nd,杰克应该是 59 岁,第二天他应该是 60 岁。应考虑闰年等。

【问题讨论】:

【参考方案1】:

为了计算两个日期之间的年数和月数,我使用了这个函数

  def calculate_year_month(from_date, to_date)
    num_days = (from_date - to_date).to_i
    num_months = (num_days / 30) 
    num_years = (num_months / 12) 
    num_months = (num_months % 12) 
    return num_years.to_s + " year(s) and " + num_months.to_s + " month(s)" 
  end 

【讨论】:

【参考方案2】:

基于与@FMc 类似的推理,我想出了以下内容 首先,计算今天年份和生日年份之间的差异。然后,将其与生日相加并检查结果日期:如果大于今天,则将 diff 减 1。 用于 Rails 应用程序,因为它依赖于 ActiveSupportyears 方法

def age(birthday, today)
  diff = today.year - birthday.year
  (birthday + diff.years > today ) ? (diff - 1) : diff
end

【讨论】:

【参考方案3】:

d2.year - d1.year - (d2.month &gt; d1.month || (d2.month == d1.month &amp;&amp; d2.day &gt;= d1.day) ? 0 : 1)

【讨论】:

欢迎来到 SO!请尝试在您的答案中提供一些解释。【参考方案4】:

您可以使用 ruby​​ gem adroit-age

它也适用于闰年..

age = AdroitAge.find_age("23/01/1990")

更新

require 'adroit-age'

dob =  Date.new(1990,1,23)
or
dob = "23/01/1990".to_date

age = dob.find_age
#=> 23

【讨论】:

【参考方案5】:

这个怎么样:

def age_in_years(date)
  # Difference in years, less one if you have not had a birthday this year.
  today = Date.today
  age = today.year - date.year
  age = age - 1 if [date.day, date.month, today.year].join('/').to_date > Date.today
end

【讨论】:

【参考方案6】:

处理闰年的方法

每当您计算某个日期以来经过的年数时,您必须决定如何处理闰年。这是我的方法,我认为它非常易读,并且能够在不使用任何“特殊情况”逻辑的情况下从容应对闰年。

def years_completed_since(start_date, end_date)

  if end_date < start_date
    raise ArgumentError.new(
      "End date supplied (#end_date) is before start date (#start_date)"
    )
  end

  years_completed = end_date.year - start_date.year

  unless reached_anniversary_in_year_of(start_date, end_date)
    years_completed -= 1
  end

  years_completed
end

# No special logic required for leap day; its anniversary in a non-leap
# year is considered to have been reached on March 1.
def reached_anniversary_in_year_of(original_date, new_date)
  if new_date.month == original_date.month
    new_date.day >= original_date.day
  else
    new_date.month > original_date.month
  end
end

【讨论】:

【参考方案7】:

http://github.com/radar/dotiw

Jack is <%= distance_of_time_in_words (Time.now, Time.local(1950,03,22)) %> old.

生产

Jack is 60 years old

【讨论】:

【参考方案8】:

我认为这将始终有效,即使对于生日临近闰日的人:

require 'date'

def calculate_age(start_date, end_date)
  end_date.year - start_date.year - ((end_date.month > start_date.month || (end_date.month == start_date.month && end_date.day >= start_date.day)) ? 0 : 1)
end

puts calculate_age( Date.strptime('03/02/1968', '%m/%d/%Y'), Date.strptime('03/02/2010', '%m/%d/%Y'))

在上面的示例调用中使用此方法计算的年龄是 42,尽管 1968 年是闰年并且生日接近闰日,但这是正确的。

另外,这样就不需要创建局部变量了。

【讨论】:

【参考方案9】:

与 FM 的想法相同,但使用了简化的 if 语句。显然,您可以添加第二个参数而不是使用当前时间。

def age(birthdate)
  now = DateTime.now
  age = now.year - birthdate.year
  age -= 1 if(now.yday < birthdate.yday)
  age
end

【讨论】:

yday 是一个很酷的功能,谢谢。不幸的是,如果这个人的出生时间晚于二月,它将以不同的方式处理闰年。 同意帕维尔。由于闰年,yday 对于比较跨年份的日期没有用处。【参考方案10】:

您想要人们通常理解的年龄,还是想要精确测量经过的时间?如果是前者,则无需担心闰年和其他并发症。如果这个人今年还没有过生日,你只需要计算年差并减少它。如果是后者,您可以按照其他答案的建议将经过的秒数转换为年数。

def age_in_completed_years (bd, d)
    # Difference in years, less one if you have not had a birthday this year.
    a = d.year - bd.year
    a = a - 1 if (
         bd.month >  d.month or 
        (bd.month >= d.month and bd.day > d.day)
    )
    a
end

birthdate = Date.new(2000, 12, 15)
today     = Date.new(2009, 12, 14)

puts age_in_completed_years(birthdate, today)

【讨论】:

看来你不仅回答了问题,还把问题表述得更好:-) +1,但是如果我出生在 Date.new(1980, 2, 29) 上呢? ;-) @Mike Bummer -- 你没有生日。好点子。修复了代码。 不知何故你知道 &*^$@ 闰年问题并没有那么平静地消失...... @Telemachus 确实!闰年老人是个顽固的混蛋。【参考方案11】:

我有一个名为 dotiw 的 gem/插件,它有一个 distance_of_time_in_words_hash,它将返回一个哈希值,例如: :years =&gt; 59, :months =&gt; 11, :days =&gt; 27 。从中您可以计算出它是否接近某个限制。

【讨论】:

【参考方案12】:

比如:

def years_diff(from_time,to_time)
  (((to_time - from_time).abs)/ (365 * 24 * 60 * 60)).to_i
end

years_diff(Time.now,Time.local(1950,03,22)) #=> 59
years_diff(Time.now,Time.local(2009,03,22)) #=> 0
years_diff(Time.now,Time.local(2008,03,22)) #=> 1

【讨论】:

当当前日期接近生日(闰年!)时,这将不起作用,并且对于超过 1460 岁的人来说,它会产生越来越多的错误。【参考方案13】:
require 'date'

def years_since(dt)
    delta = (Date.today - Date.parse(dt)) / 365
    delta.to_i
end

【讨论】:

以上是关于如何计算Ruby中给定日期以来已经过去了多少年?的主要内容,如果未能解决你的问题,请参考以下文章

java设计一个方法返回今天距离过去的某一天已经过去了多少天

过去的文本日期到几天(自)PHP

excel中如何计算出 两个日期之间相差是多少年、月、日? 日期的格式是:2011-9-7。

如何提取自特定日期以来进行过交易的客户? (活跃客户定义)

php 计算两个日期相隔多少年,多少月,多少天

(用JAVA实现)请使用日期相关的api,控制台输入出生日期,计算出一个人出生了多少年?