2009-12-14 61 views
14

這個問題在這裏用於其他語言,所以讓我們來看看Ruby的一個。如何計算從給定日期以來在Ruby中經過了多少年?

如何計算從給定日期過去的完整年數?正如你可能猜到的那樣,這是自動計算人的年齡。最近的一個是distance_of_time_in_words Rails的幫手,讓下面的模板

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解決方案會更好。

編輯:問題的要點是需要一個非近似的解決方案。在三月的2 nd傑克應該59歲,第二天他應該是60歲。應考慮閏年等。

回答

37

你想年齡的人通常的理解,或者是你在尋找逝去的時間精確測量?如果前者,則不必擔心閏年和其他併發症。如果這個人今年還沒有過生日,那麼你只需要計算幾年的差異並減少它。如果是後者,則可以將已經過的秒數轉換成年,如其他答案所建議的那樣。

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

看來你不是隻回答了這個問題,而是以更好的方式提出了這個問題:-) – 2009-12-15 00:35:12

+1

+1,但是如果我出生了,比如說Date.new(1980,2,29)呢? ;-) – 2009-12-15 08:54:08

+1

@Mike Bummer - 沒有你的生日。好點子。修復了代碼。 – FMc 2009-12-15 12:43:24

4
require 'date' 

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

如何像:

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 
+1

這會不會,如果是大於今天,減少差異在當前日期接近生日(閏年!)時工作,而對於超過1460年的人來說,這會產生越來越大的錯誤。 – 2009-12-14 23:47:26

5

我有一個名爲dotiw寶石/插件具有distance_of_time_in_words_hash,將返回的哈希,如:{ :years => 59, :months => 11, :days => 27 }。從中可以看出它是否接近某個極限。

1

與FM相同的想法,但具有簡化的if語句。顯然,你可以添加第二個參數,而不是使用當前時間。

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

'yday'是一個很酷的功能,謝謝。不幸的是,如果這個人的出生時間晚於二月,那麼它將以不同的方式處理閏年。 – 2009-12-17 06:24:08

+0

同意帕維爾。 'yday'對比較因閏年而跨越數年的日期無用。 – 2017-01-07 06:15:11

1

我認爲這會一直工作,甚至有人用近一個閏日生日:

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年是閏年,生日接近閏日。

另外,這種方式不需要創建局部變量。

4

該處理閏年

每當你因爲一個日期計算經過幾年,你必須決定如何處理的飛躍的方法年。這是我的方法,我認爲它非常可讀,並且能夠在不使用任何「特殊情況」邏輯的情況下跨越閏年。

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 
0

如何:

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 
2

可以使用紅寶石寶石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 
0

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

+0

歡迎來到SO!請嘗試爲您的答案提供一些解釋。 – codeMagic 2014-01-09 00:38:57

1

我想出了下面,基於類似的推理@FMc 首先,計算今天的一年生日的年份之間的差異。然後,總結生日並檢查所生成日期:1。 要在Rails應用中使用,因爲它依賴於ActiveSupportyears方法

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