Skip to content

Instantly share code, notes, and snippets.

@mrpunkin
Last active August 29, 2015 13:57
Show Gist options
  • Select an option

  • Save mrpunkin/9536717 to your computer and use it in GitHub Desktop.

Select an option

Save mrpunkin/9536717 to your computer and use it in GitHub Desktop.
A simple, light-weight script that sets up a new ActiveSupport::Duration class to handle weekdays.
module Weekdays
module NumericExtensions
def weekdays
Weekday.new(self)
end
alias :weekday :weekdays
end
module TimeExtensions
def weekday?
(1..5) === self.wday
end
end
class Weekday < ActiveSupport::Duration
def initialize(days)
super(days * 24.hours, [[:weekdays, days]])
end
def inspect
parts.
reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
sort_by {|unit, _ | [:years, :months, :weekdays, :days, :minutes, :seconds].index(unit)}.
map {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}.
to_sentence(:locale => :en)
end
private
def sum(sign, time = ::Time.current) #:nodoc:
parts.inject(time) do |t,(type,number)|
if t.acts_like?(:time) || t.acts_like?(:date)
workdays = 0
while number > 0
time += 1.day
workdays += 1
number -= 1 if time.weekday? ## Only count down if it counts as a weekday
end
t.advance(:days => sign * workdays)
else
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
end
end
end
end
end
Numeric.send(:include, Weekdays::NumericExtensions)
Date.send(:include, Weekdays::TimeExtensions)
Time.send(:include, Weekdays::TimeExtensions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment