diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ae0d19 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.sw? +.DS_Store +coverage +rdoc +pkg +*.bundle +*.so +*.dll +*.o +Makefile +*.gemspec diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6d10f42 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 Burke Libbey, Thorkelson Consulting Ltd. + +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. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..c007f30 --- /dev/null +++ b/Rakefile @@ -0,0 +1,3 @@ +require 'rubygems' +require 'rake' + diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/lib/business_days.rb b/lib/business_days.rb new file mode 100644 index 0000000..013aa22 --- /dev/null +++ b/lib/business_days.rb @@ -0,0 +1,36 @@ +require 'active_support/all' +require File.join(File.dirname(__FILE__),'business_days','time') + +module BusinessDays + + class BusinessDayDuration + def initialize(days) + @days = days + end + + def calculate_duration(time, operation) + business_days = time.is_business_day? ? 1 : 0 + while business_days <= @days + if (time = time.send(operation, 1.day)).is_business_day? + business_days += 1 + end + end + time + end + + def +(time) + calculate_duration(time, :+) + end + + end + + def business_days + BusinessDayDuration.new(self) + end + alias :business_day :business_days + +end + +class Numeric + include BusinessDays +end diff --git a/lib/business_days/time.rb b/lib/business_days/time.rb new file mode 100644 index 0000000..da8e56c --- /dev/null +++ b/lib/business_days/time.rb @@ -0,0 +1,42 @@ +module BusinessDays + module Time + module Calculations + def self.included(base) #:nodoc: + + base.class_eval do + alias_method :plus_without_business_days, :+ + alias_method :+, :plus_with_business_days + + alias_method :minus_without_business_days, :- + alias_method :-, :minus_with_business_days + end + end + + def is_business_day? + # TODO: Holidays. + ! [0,6].include?(self.wday) + end + + def plus_with_business_days(other) + if BusinessDays::BusinessDayDuration === other + other.calculate_duration(self, :+) + else + plus_without_business_days(other) + end + end + + def minus_with_business_days(other) + if BusinessDays::BusinessDayDuration === other + other.calculate_duration(self, :-) + else + minus_without_business_days(other) + end + end + end + + end +end + +class Time + include BusinessDays::Time::Calculations +end diff --git a/spec/business_days_spec.rb b/spec/business_days_spec.rb new file mode 100644 index 0000000..2b853db --- /dev/null +++ b/spec/business_days_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' +require File.join(File.dirname(__FILE__),'..','lib','business_days') + +describe BusinessDays do + + before do + @friday = Time.parse("Friday, September 10th, 2010") + @thursday = @friday - 1.day + @saturday = @friday + 1.day + @monday = @friday + 3.days + @tuesday = @friday + 4.days + end + + it "should add properly" do + (@friday + 1.business_day).should == @monday + (@friday + 2.business_days).should == @tuesday + (@saturday + 1.business_days).should == @tuesday + (@saturday + 0.business_days).should == @monday + end + + it "should subtract properly" do + (@saturday - 0.business_days).should == @friday + (@saturday - 1.business_day).should == @thursday + (@monday - 1.business_days).should == @friday + (@monday - 0.business_days).should == @monday + end + + it "should add with the params reversed" do + (1.business_day + @friday).should == @monday + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..9e9cffc --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,11 @@ +require 'rubygems' + +# require something. + +gem "rspec", ">=1.2.5" + +Spec::Runner.configure do |config| + +end + + diff --git a/spec/spec_opts.rb b/spec/spec_opts.rb new file mode 100644 index 0000000..cf6add7 --- /dev/null +++ b/spec/spec_opts.rb @@ -0,0 +1 @@ +--colour \ No newline at end of file