誕生日から人の年齢を教えてください。now - birthday / 365
一部の年には366日あるため、機能しません。私は次のコードを思いつきました:
now = Date.today
year = now.year - birth_date.year
if (date+year.year) > now
year = year - 1
end
年齢を計算するよりRubyっぽい方法はありますか?
誕生日から人の年齢を教えてください。now - birthday / 365
一部の年には366日あるため、機能しません。私は次のコードを思いつきました:
now = Date.today
year = now.year - birth_date.year
if (date+year.year) > now
year = year - 1
end
年齢を計算するよりRubyっぽい方法はありますか?
回答:
私はここでパーティーに遅れていることを知っていますが、うるう年の2月29日に生まれた人の年齢を計算しようとすると、受け入れられた答えはひどく壊れます。これは、を呼び出すとbirthday.to_date.change(:year => now.year)
無効な日付が作成されるためです。
代わりに次のコードを使用しました。
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
true
||の代わりに1 false
?
私はこの解決策がうまく機能し、他の人が読めることを発見しました:
age = Date.today.year - birthday.year
age -= 1 if Date.today < birthday + age.years #for days before birthday
簡単で、うるう年などの扱いを気にする必要はありません。
Date.today.month < birthday.month or Date.today.month == birthday.month && Date.today.mday < birthday.mday
。
これを使って:
def age
now = Time.now.utc.to_date
now.year - birthday.year - (birthday.to_date.change(:year => now.year) > now ? 1 : 0)
end
rails/activesupport
です。
Ruby on Rails(ActiveSupport)の1つのライナー。うるう年、うるう秒などを扱います。
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()
に呼び出されない場合。
(Date.today.to_s(:number).to_i - birthday.to_date.to_s(:number).to_i)/1e4.to_i
また、動作します
(Date.today.strftime('%Y%m%d').to_i - dob.strftime('%Y%m%d').to_i) / 10000
これまでの答えはちょっと変です。あなたの最初の試みはこれを行う正しい方法にかなり近かったです:
birthday = DateTime.new(1900, 1, 1)
age = (DateTime.now - birthday) / 365.25 # or (1.year / 1.day)
小数の結果が得られるので、結果をで整数に変換してくださいto_i
。これは、イベント以降の日数の差を日数(または関連するTimeクラスの場合は秒数)で測定される期間として正しく処理するため、より優れたソリューションです。次に、1年の日数で単純に除算すると、年齢がわかります。この方法で年数を計算する場合、元のDOB値を保持している限り、うるう年を考慮に入れる必要はありません。
birthday = DateTime.now - 1.year
年齢は0です。残念ながら、365.25で割ると少し不正確になります。
私のおすすめ:
def age(birthday)
((Time.now - birthday.to_time)/(60*60*24*365)).floor
end
トリックは、Timeを使用したマイナス操作が秒を返すことです。
私はこれが好きです:
now = Date.current
age = now.year - dob.year
age -= 1 if now.yday < dob.yday
この回答が最善です。代わりに賛成してください。
@philnashのソリューションは好きですが、条件付きの方がコンパクトになる可能性があります。そのブール式が行うことは、辞書式順序を使用して[月、日]のペアを比較することです。そのため、代わりにルビーの文字列比較を使用できます。
def age(dob)
now = Date.today
now.year - dob.year - (now.strftime('%m%d') < dob.strftime('%m%d') ? 1 : 0)
end
(Date.today.strftime('%Y%m%d').to_i - dob.strftime('%Y%m%d').to_i) / 10000
ですか?
これは、この回答の変換です(多くの票を獲得しています):
# 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
Ruby on Railsには、タグ付けされているので、dotiw逸品Railsは組み込みの上書きされますdistance_of_times_in_wordsと提供distance_of_times_in_words_hash年齢を決定するために使用することができます。うるう年は年の部分では問題なく処理されますが、2月29日は日数の部分に影響を及ぼし、そのレベルの詳細が必要かどうかを理解する必要があることに注意してください。また、dotiwがどのようにdistance_of_time_in_wordsのフォーマットを変更するのが気に入らない場合は、:vagueオプションを使用して元のフォーマットに戻します。
Gemfileにdotiwを追加します。
gem 'dotiw'
コマンドラインで:
bundle
適切なモデルにDateHelperを含めて、distance_of_time_in_wordsおよびdistance_of_time_in_words_hashにアクセスします。この例では、モデルは「User」であり、誕生日フィールドは「birthday」です。
class User < ActiveRecord::Base
include ActionView::Helpers::DateHelper
このメソッドを同じモデルに追加します。
def age
return nil if self.birthday.nil?
date_today = Date.today
age = distance_of_time_in_words_hash(date_today, self.birthday).fetch("years", 0)
age *= -1 if self.birthday > date_today
return age
end
使用法:
u = User.new("birthday(1i)" => "2011", "birthday(2i)" => "10", "birthday(3i)" => "23")
u.age
これは@philnashの回答と機能的に同等であると思いますが、IMOの方が理解しやすいです。
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
これはどうですか?
def age
return unless dob
t = Date.today
age = t.year - dob.year
b4bday = t.strftime('%m%d') < dob.strftime('%m%d')
age - (b4bday ? 1 : 0)
end
これは、レールを使用age
してモデルのメソッドを呼び出し、モデルに日付データベース列があることを前提としていますdob
。このメソッドは文字列を使用して今年の誕生日より前かどうかを判断するため、これは他の回答とは異なります。
たとえばdob
、today
が2004/2/28で2014/2/28の場合、age
は2014 - 2004
またはになります10
。フロートになります0228
と0229
。b4bday
なります"0228" < "0229"
かtrue
。最後に、1
から減算しage
て取得し9
ます。
これは、2つの時間を比較する通常の方法です。
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
これは同じように機能しますが、b4bday
ラインが長すぎます。2016
今年も不要です。最初の文字列比較が結果でした。
これもできます
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 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```
def birthday(user)
today = Date.today
new = user.birthday.to_date.change(:year => today.year)
user = user.birthday
if Date.civil_to_jd(today.year, today.month, today.day) >= Date.civil_to_jd(new.year, new.month, new.day)
age = today.year - user.year
else
age = (today.year - user.year) -1
end
age
end
Time.now.year - self.birthdate.year - (birthdate.to_date.change(:year => Time.now.year) > Time.now.to_date ? 1 : 0)
うるう年を考慮に入れるには(およびactivesupportの存在を想定):
def age
return unless birthday
now = Time.now.utc.to_date
years = now.year - birthday.year
years - (birthday.years_since(years) > now ? 1 : 0)
end
years_since
うるう年以外の年を考慮に入れるように日付が正しく変更されます(誕生日がの場合02-29
)。
これは、特定の日付の年齢を計算することもできる私の解決策です:
def age on = Date.today
(_ = on.year - birthday.year) - (on < birthday.since(_.years) ? 1 : 0)
end
私もこれに対処しなければなりませんでしたが、何ヶ月もかかりました。あまりにも複雑になりました。私が考えることができる最も簡単な方法は:
def month_number(today = Date.today)
n = 0
while (dob >> n+1) <= today
n += 1
end
n
end
12か月で同じことができます。
def age(today = Date.today)
n = 0
while (dob >> n+12) <= today
n += 1
end
n
end
これはDateクラスを使用して月をインクリメントし、28日やうるう年などを扱います。