lib/timeframe.rb in timeframe-0.1.0 vs lib/timeframe.rb in timeframe-0.1.1
- old
+ new
@@ -1,10 +1,12 @@
require 'date'
require 'multi_json'
require 'active_support/version'
require 'active_support/core_ext' if ActiveSupport::VERSION::MAJOR >= 3
+require 'timeframe/iso_8601'
+
# Encapsulates a timeframe between two dates. The dates provided to the class are always until the last date. That means
# that the last date is excluded.
#
# # from 2007-10-01 00:00:00.000 to 2007-10-31 23:59:59.999
# Timeframe.new(Date(2007,10,1), Date(2007,11,1))
@@ -41,12 +43,18 @@
end
# Construct a new Timeframe by parsing an ISO 8601 time interval string
# http://en.wikipedia.org/wiki/ISO_8601#Time_intervals
def from_iso8601(str)
- raise ArgumentError, 'Intervals should be specified according to ISO 8601, method 1, eliding times' unless str =~ /^\d\d\d\d-\d\d-\d\d\/\d\d\d\d-\d\d-\d\d$/
- new *str.split('/')
+ delimiter = str.include?('/') ? '/' : '--'
+ a_raw, b_raw = str.split delimiter
+ if a_raw.blank? or b_raw.blank?
+ raise ArgumentError, "Interval must be specified according to ISO 8601 <start>/<end>, <start>/<duration>, or <duration>/<end>."
+ end
+ a = Iso8601::A.new a_raw
+ b = Iso8601::B.new b_raw
+ new a.to_time(b), b.to_time(a)
end
# Construct a new Timeframe from a hash with keys startDate and endDate
def from_hash(hsh)
hsh = hsh.symbolize_keys
@@ -66,18 +74,18 @@
when ::Hash
from_hash input
when ::String
str = input.strip
if str.start_with?('{')
- from_hash ::MultiJson.decode(str)
+ from_hash MultiJson.decode(str)
elsif input =~ /\A\d\d\d\d\z/
from_year input
else
from_iso8601 str
end
else
- raise ::ArgumentError, "Must be String or Hash"
+ raise ArgumentError, "Must be String or Hash"
end
end
alias :interval :parse
alias :from_json :parse
@@ -254,11 +262,11 @@
a = [ start_date ] + timeframes.collect(&:end_date)
b = timeframes.collect(&:start_date) + [ end_date ]
a.zip(b).map do |gap|
- Timeframe.new(*gap, :skip_year_boundary_crossing_check => true) if gap[1] > gap[0]
+ Timeframe.new(*gap) if gap[1] > gap[0]
end.compact
end
# Returns true if the union of the given Timeframes includes the Timeframe
def covered_by?(*timeframes)
@@ -282,10 +290,30 @@
def iso8601
"#{start_date.iso8601}/#{end_date.iso8601}"
end
alias :to_s :iso8601
alias :to_param :iso8601
-
+
+ def dates
+ dates = []
+ cursor = start_date
+ while cursor < end_date
+ dates << cursor
+ cursor = cursor.succ
+ end
+ dates
+ end
+
+ def first_days_of_months
+ dates = []
+ cursor = start_date.beginning_of_month
+ while cursor < end_date
+ dates << cursor
+ cursor = cursor >> 1
+ end
+ dates
+ end
+
# Deprecated
def from # :nodoc:
@start_date
end