diff options
-rw-r--r-- | lib/ayk/age.rb | 70 | ||||
-rw-r--r-- | spec/age.rb | 97 | ||||
-rw-r--r-- | spec/age_spec.rb | 82 |
3 files changed, 135 insertions, 114 deletions
diff --git a/lib/ayk/age.rb b/lib/ayk/age.rb index 0ecc40e..f51b8f1 100644 --- a/lib/ayk/age.rb +++ b/lib/ayk/age.rb @@ -1,37 +1,73 @@ #! /usr/bin/env ruby # -*- coding: UTF-8 -*- - -#---------------------------------------------------------------------------- # -# File : age.rb -# Author : Jérémy Zurcher <jeremy@asynk.ch> -# Date : 22/08/09 +# Copyright (c) 2009-2011 Jérémy Zurcher +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # #---------------------------------------------------------------------------- - +# require 'date' - +# class DateTime # returns an array representing years,months,days,hours,minutes,seconds # between self and futur DateTime at def age at=DateTime.now return [nil]*6 if at<self - # years + return [0]*6 if at==self years = at.year-self.year + months = at.month-self.month + # move years forward x = self>>(12*years) if x>at - years -= 1 - x<<=12 - end - months = at.month-x.month+(11*(at.year-x.year)) - x >>=months - if x>at - months -= 1 - x <<=1 + # move months backward + x>>=months + # adjust years and months + years-=1 + months+=12 + else + # move months forward + x>>=months end - # days days = (at-x).to_i + if days<0 + # move 1 month backward + x<<=1 + # adjust months and days + months-=1 + days = (at-x).to_i + end + # move days forward x += days + if x>at + # move 1 day backward + x-=1 + days-=1 + if days<0 + x+=1 + x<<=1 + months-=1 + days = (at-x).to_i + x+=days + end + end # hours hours,r = (at.to_time-x.to_time).to_i.divmod 3600 mins,secs = r.divmod 60 diff --git a/spec/age.rb b/spec/age.rb deleted file mode 100644 index 1e4c9a8..0000000 --- a/spec/age.rb +++ /dev/null @@ -1,97 +0,0 @@ -#! /usr/bin/env ruby -# -*- coding: UTF-8 -*- - -require 'ayk/age' -# -def age_spec(birth,dy,dm,dd) - at = ((birth>>(12*dy))>>dm)+dd -# puts at.strftime "%d.%m.%Y" - y,m,d,h,i,s = birth.age(at) -# puts "#{y} #{m} #{d}" - y.should eql dy - m.should eql dm - d.should eql dd -end -# -describe DateTime do - # - before(:all) do - @b = DateTime.civil 2009,7,27,4,40,0 # Róisín Mannion-Zurcher [IRL|CH] ) - end - it "should pass time checks" do - y,m,d,h,i,s = @b.age( DateTime.civil(2009,7,27,4,40,0) ) - h.should eql 0 - i.should eql 0 - s.should eql 0 - y,m,d,h,i,s = @b.age( DateTime.civil(2009,7,27,7,2,2) ) - h.should eql 2 - i.should eql 22 - s.should eql 2 - end - it "simple checks" do - age_spec(@b,0,0,0) - age_spec(@b,0,0,1) - age_spec(@b,0,1,0) - age_spec(@b,0,1,1) - age_spec(@b,1,0,0) - age_spec(@b,1,0,1) - age_spec(@b,1,1,0) - age_spec(@b,1,1,1) - end - it "should pass day computations" do - at = ((@b>>(12*0))>>15)+3 - y,m,d,h,i,s = @b.age(at) - y.should eql 1 - m.should eql 3 - d.should eql 3 - at = ((@b>>(12*0))>>1)+366 - y,m,d,h,i,s = @b.age(at) - y.should eql 1 - m.should eql 1 - d.should eql 1 - at = ((@b>>(12*5))>>10)+15 - y,m,d,h,i,s = @b.age(at) - y.should eql 5 - m.should eql 10 - d.should eql 15 - at = ((@b>>(12*0))>>0)+750 - y,m,d,h,i,s = @b.age(at) - y.should eql 2 - m.should eql 0 - d.should eql 20 - end - it "should pass more complicated one" do - at = DateTime.civil 2010,7,13,4,40,0 # Corina Mannion - y,m,d,h,i,s = @b.age(at) - y.should eql 0 - m.should eql 11 - d.should eql 16 - h.should eql 0 - i.should eql 0 - s.should eql 0 - at = DateTime.civil 2010,7,13,0,0,0 # Corina Mannion - y,m,d,h,i,s = @b.age(at) - y.should eql 0 - m.should eql 11 - d.should eql 15 - h.should eql 19 - i.should eql 20 - s.should eql 0 - end - it "should correctly handle 1 year -1 day " - y,m,d,h,i,s = @b.age( DateTime.civil(2009,7,26,4,40,0) ) - y.should eql 0 - m.should eql 11 - d.should eql 15 - h.should eql 19 - i.should eql 20 - s.should eql 0 - end -end - - -#(1..365).each do |n| -# dt = birth.age( birth+n) -# puts "#{n} => #{dt[1]} #{dt[2]}" -#end - diff --git a/spec/age_spec.rb b/spec/age_spec.rb new file mode 100644 index 0000000..7c447e0 --- /dev/null +++ b/spec/age_spec.rb @@ -0,0 +1,82 @@ +#! /usr/bin/env ruby +# -*- coding: UTF-8 -*- + +require 'ayk/age' +# +def age_spec birth, dy, dm, dd + at = (birth>>(12*dy+dm))+dd + y,m,d,hh,mm,ss = birth.age(at) + y.should eql dy + m.should eql dm + d.should eql dd + hh.should eql 0 + mm.should eql 0 + ss.should eql 0 +end +def full_check birth, at, y, m, d, hh, mm, ss + r = birth.age at + r[0].should eql y + r[1].should eql m + r[2].should eql d + r[3].should eql hh + r[4].should eql mm + r[5].should eql ss + x = ((birth>>(12*y+m))+d+(hh/24.0)+(mm/1440.0)+(ss/86400.0)) + x.year.should eql at.year + x.month.should eql at.month + x.day.should eql at.day + x.hour.should eql at.hour +# x.minute.should eql at.minute +# x.second.should eql at.second +end +# +describe DateTime do + # + before(:all) do + @b = DateTime.civil 2009,7,27,4,40,0 # Róisín Mannion-Zurcher [IRL|CH] ) + end + it "should pass basic futur checks" do + age_spec(@b,0,0,0) + age_spec(@b,0,0,1) + age_spec(@b,0,1,0) + age_spec(@b,0,1,1) + age_spec(@b,1,0,0) + age_spec(@b,1,0,1) + age_spec(@b,1,1,0) + age_spec(@b,1,1,1) + end + it "should pass 10000 days computation" do + (0..10000).each do |n| + at = @b+n + r = @b.age at + x = (@b>>(12*r[0]+r[1]))+r[2] + x.year.should eql at.year + x.month.should eql at.month + x.day.should eql at.day + end + end + it "should pass time computation" do + full_check @b, DateTime.civil( 2010, 9, 25, 3, 40, 0), 1, 1, 28, 23, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 25, 4, 39, 0), 1, 1, 28, 23, 59, 0 + full_check @b, DateTime.civil( 2010, 9, 25, 4, 39, 59), 1, 1, 28, 23, 59, 59 + full_check @b, DateTime.civil( 2010, 9, 25, 4, 40, 0), 1, 1, 29, 0, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 26, 3, 40, 0), 1, 1, 29, 23, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 26, 4, 39, 0), 1, 1, 29, 23, 59, 0 + full_check @b, DateTime.civil( 2010, 9, 26, 4, 39, 59), 1, 1, 29, 23, 59, 59 + full_check @b, DateTime.civil( 2010, 9, 26, 4, 40, 0), 1, 1, 30, 0, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 27, 3, 40, 0), 1, 1, 30, 23, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 27, 4, 39, 0), 1, 1, 30, 23, 59, 0 + full_check @b, DateTime.civil( 2010, 9, 27, 4, 39, 59), 1, 1, 30, 23, 59, 59 + full_check @b, DateTime.civil( 2010, 9, 27, 4, 40, 0), 1, 2, 0, 0, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 28, 3, 40, 0), 1, 2, 0, 23, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 28, 4, 39, 0), 1, 2, 0, 23, 59, 0 + full_check @b, DateTime.civil( 2010, 9, 28, 4, 39, 59), 1, 2, 0, 23, 59, 59 + full_check @b, DateTime.civil( 2010, 9, 28, 4, 40, 0), 1, 2, 1, 0, 0, 0 + full_check @b, DateTime.civil( 2010, 9, 29, 3, 40, 0), 1, 2, 1, 23, 0, 0 + # change years + full_check @b, DateTime.civil( 2010, 7, 27, 4, 40, 0), 1, 0, 0, 0, 0, 0 + full_check @b, DateTime.civil( 2010, 7, 27, 3, 40, 0), 0, 11, 29, 23, 0, 0 + full_check @b, DateTime.civil( 2010, 7, 27, 4, 39, 0), 0, 11, 29, 23, 59, 0 + full_check @b, DateTime.civil( 2010, 7, 27, 4, 39, 59), 0, 11, 29, 23, 59, 59 + end +end |