Hi! I''m at my wits end with this problem and hopefully someone can help me. I have code to calculate age based on date of death - date of birth. I want the age to calculate down to the minute, which it is. However, I have to account for all age units: minutes, hours, days, months, or years. My problem is that I need to have if statements set up for every scenario, but I want to exit the model when the correct age unit has been established. Rails is continuting to evaluate the other if statements, even when I''m checking for nil, and ends up returning 0 in the case of an age unit less than a year. I have tried assembling the if statements in a number of ways, including using a "return" statement when the correct age unit has been calculated. This works, but the model returns an error if there is more than one return statement in existence. I just don''t know what else to try!! Any help would be GREATLY appreciated!! Here''s my code: def age dod = self.precase.report.dod @age ||= begin a = read_attribute(:age) dateofbirth = read_attribute(:dob) if not dateofbirth.nil? if not dod.nil? seconds = dod.to_time - dateofbirth.to_time minutes = seconds / 60 m = minutes.to_i if m.between?(1, 59) m end hours = minutes / 60 h = hours.to_i if not h.nil? if h.between?(1, 23) h end end days = h / 24 d = days.to_i if not d.nil? if d.between?(1, 30) d end end months = days / 30 mths = months.to_i if not mths.nil? if mths.between?(1, 11) mths else years = dod.year - dob.year-(dob.to_time.change(:year => dod.year) > dod ? 1 : 0) end end end end end end --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 2, 1:13 pm, "Ali" <awilli...-KQhSGARDxiOeQVqA2Ba1Pg@public.gmane.org> wrote:> Hi! > > I''m at my wits end with this problem and hopefully someone can help > me. > > I have code to calculate age based on date of death - date of birth. > I want the age to calculate down to the minute, which it is. However, > I have to account for all age units: minutes, hours, days, months, or > years. My problem is that I need to have if statements set up for > every scenario, but I want to exit the model when the correct age unit > has been established. Rails is continuting to evaluate the other if > statements, even when I''m checking for nil, and ends up returning 0 in > the case of an age unit less than a year. I have tried assembling the > if statements in a number of ways, including using a "return" > statement when the correct age unit has been calculated. This works, > but the model returns an error if there is more than one return > statement in existence. I just don''t know what else to try!! Any > help would be GREATLY appreciated!! > > Here''s my code: > > def age > dod = self.precase.report.dod > > @age ||= begin > a = read_attribute(:age) > dateofbirth = read_attribute(:dob) > if not dateofbirth.nil? > if not dod.nil? > > seconds = dod.to_time - dateofbirth.to_time > minutes = seconds / 60 > m = minutes.to_i > > if m.between?(1, 59) > m > end > > hours = minutes / 60 > h = hours.to_i > > if not h.nil? > if h.between?(1, 23) > h > end > end > > days = h / 24 > d = days.to_i > > if not d.nil? > if d.between?(1, 30) > d > end > end > > months = days / 30 > mths = months.to_i > > if not mths.nil? > if mths.between?(1, 11) > mths > else > years = dod.year - dob.year-(dob.to_time.change(:year > => dod.year) > dod ? 1 : 0) > end > end > end > end > end > endCouple of things here... 1. use the ''ruby-units'' gem to help with the unit conversions 2. use a ''case'' require ''rubygems'' require ''ruby-units'' require ''date'' dob = DateTime.new(1969,4,24,10,30,0) dod = DateTime.new(2068,1,31,11,30,0) age = dod.unit - dob.unit @age = age.to case when age < ''1 min''.unit : ''sec'' when age < ''1 hr''.unit : ''min'' when age < ''1 day''.unit : ''hour'' when age < ''1 week''.unit : ''day'' when age < ''1 year''.unit : ''week'' when age < ''10 years''.unit : ''year'' when age < ''100 years''.unit : ''decade'' else ''century'' end puts "#{''%0.2f'' % @age}" #=> 9.88 decade Note that ruby-units doesn''t define a ''month'' unit (because it isn''t fixed). But you can define one that is 30 days long if you like. You also want to use the format string in the to_s or you get this... 15900642/15778463 century Because DateTime likes to make things Rational. If you want the output to match the units of another compatible unit just pass it in the ''to'' call age = ''9.88 decade''.unit another_age = ''77 year''.unit age.to(another_age) #=> 98.8 year As you can also see, if you have a string that defines your target unit, you just need to do... age.to(target_unit) _Kevin --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 2, 2:32 pm, "_Kevin" <kevin.olbr...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Feb 2, 1:13 pm, "Ali" <awilli...-KQhSGARDxiOeQVqA2Ba1Pg@public.gmane.org> wrote: > > > > > Hi! > > > I''m at my wits end with this problem and hopefully someone can help > > me. > > > I have code to calculate age based on date of death - date of birth. > > I want the age to calculate down to the minute, which it is. However, > > I have to account for all age units: minutes, hours, days, months, or > > years. My problem is that I need to have if statements set up for > > every scenario, but I want to exit the model when the correct age unit > > has been established. Rails is continuting to evaluate the other if > > statements, even when I''m checking for nil, and ends up returning 0 in > > the case of an age unit less than a year. I have tried assembling the > > if statements in a number of ways, including using a "return" > > statement when the correct age unit has been calculated. This works, > > but the model returns an error if there is more than one return > > statement in existence. I just don''t know what else to try!! Any > > help would be GREATLY appreciated!! > > > Here''s my code: > > > def age > > dod = self.precase.report.dod > > > @age ||= begin > > a = read_attribute(:age) > > dateofbirth = read_attribute(:dob) > > if not dateofbirth.nil? > > if not dod.nil? > > > seconds = dod.to_time - dateofbirth.to_time > > minutes = seconds / 60 > > m = minutes.to_i > > > if m.between?(1, 59) > > m > > end > > > hours = minutes / 60 > > h = hours.to_i > > > if not h.nil? > > if h.between?(1, 23) > > h > > end > > end > > > days = h / 24 > > d = days.to_i > > > if not d.nil? > > if d.between?(1, 30) > > d > > end > > end > > > months = days / 30 > > mths = months.to_i > > > if not mths.nil? > > if mths.between?(1, 11) > > mths > > else > > years = dod.year - dob.year-(dob.to_time.change(:year > > => dod.year) > dod ? 1 : 0) > > end > > end > > end > > end > > end > > end > > Couple of things here... > > 1. use the ''ruby-units'' gem to help with the unit conversions > > 2. use a ''case'' > > require ''rubygems'' > require ''ruby-units'' > require ''date'' > > dob = DateTime.new(1969,4,24,10,30,0) > dod = DateTime.new(2068,1,31,11,30,0) > > age = dod.unit - dob.unit > > @age = age.to case > when age < ''1 min''.unit : ''sec'' > when age < ''1 hr''.unit : ''min'' > when age < ''1 day''.unit : ''hour'' > when age < ''1 week''.unit : ''day'' > when age < ''1 year''.unit : ''week'' > when age < ''10 years''.unit : ''year'' > when age < ''100 years''.unit : ''decade'' > else > ''century'' > end > > puts "#{''%0.2f'' % @age}" > > #=> 9.88 decade > > Note that ruby-units doesn''t define a ''month'' unit (because it isn''t > fixed). But you can define one that is 30 days long if you like. > You also want to use the format string in the to_s or you get this... > > 15900642/15778463 century > > Because DateTime likes to make things Rational. > > If you want the output to match the units of another compatible unit > just pass it in the ''to'' call > > age = ''9.88 decade''.unit > another_age = ''77 year''.unit > > age.to(another_age) #=> 98.8 year > > As you can also see, if you have a string that defines your target > unit, you just need to do... > > age.to(target_unit) > > _KevinAlmost forgot... ruby-units also supports ranges, so this works too @age = age.to case age when ''0 sec''.unit ...''1 min''.unit : ''sec'' when ''1 min''.unit ... ''1 hr''.unit : ''min'' when ''1 hr''.unit ... ''1 day''.unit : ''hour'' when ''1 day''.unit ... ''1 week''.unit : ''day'' when ''1 week''.unit ... ''1 year''.unit : ''week'' when ''1 year''.unit ... ''10 years''.unit : ''year'' when ''10 years''.unit ... ''100 years''.unit : ''decade'' else ''century'' end _Kevin --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I used the following for number of seconds in each date part: year = 365.25 * 60 * 60 * 24 = 31557600 month = year / 12 = 2629800 day = 60 * 60 * 24 = 86400 hour = 60 * 60 = 3600 minute = 60 second = 1 This function, then, returns a hash of the date parts: def age_parts(in_seconds) parts = Hash.new factors = [[''years'', 31557600],[''months'', 2629800],[''days'', 86400],[''hours'', 3600],[''minutes'',60],[''seconds'',1]] age = factors.collect do |unit, factor| value, in_seconds = in_seconds.divmod(factor) parts[unit] = value end parts end irb(main):187:0> parts = age_parts(1176095625) => {"days"=>6, "seconds"=>45, "minutes"=>43, "years"=>37, "hours"=>15, "months"=>3} irb(main):188:0> parts[''years''] => 37 irb(main):189:0> parts[''months''] => 3 irb(main):190:0> parts[''days''] => 6 irb(main):191:0> parts[''hours''] => 15 irb(main):192:0> parts[''minutes''] => 43 irb(main):193:0> parts[''seconds''] => 45 -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---