diff --git a/lib/chronic.rb b/lib/chronic.rb index 1659a929..e791b4b7 100644 --- a/lib/chronic.rb +++ b/lib/chronic.rb @@ -103,7 +103,7 @@ def self.parse(text, options = {}) # second - Integer second. # # Returns a new Time object constructed from these params. - def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, offset = nil) + def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, offset = nil, time_class = Chronic.time_class) if second >= 60 minute += second / 60 second = second % 60 @@ -139,13 +139,14 @@ def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, o month = month % 12 end end - if Chronic.time_class.name == 'Date' - Chronic.time_class.new(year, month, day) - elsif not Chronic.time_class.respond_to?(:new) or (RUBY_VERSION.to_f < 1.9 and Chronic.time_class.name == 'Time') - Chronic.time_class.local(year, month, day, hour, minute, second) + + if time_class.name == 'Date' + time_class.new(year, month, day) + elsif not time_class.respond_to?(:new) or (RUBY_VERSION.to_f < 1.9 and time_class.name == 'Time') + time_class.local(year, month, day, hour, minute, second) else - offset = Time::normalize_offset(offset) if Chronic.time_class.name == 'DateTime' - Chronic.time_class.new(year, month, day, hour, minute, second, offset) + offset = Time::normalize_offset(offset, time_class) if time_class.name == 'DateTime' + time_class.new(year, month, day, hour, minute, second, offset) end end diff --git a/lib/chronic/date.rb b/lib/chronic/date.rb index 947fed8e..fb5a7a10 100644 --- a/lib/chronic/date.rb +++ b/lib/chronic/date.rb @@ -61,9 +61,9 @@ def self.could_be_year?(year) # make_year(00, 50) #=> 2000 # # Returns The Integer 4 digit year. - def self.make_year(year, bias) + def self.make_year(year, bias, time_class = Chronic.time_class) return year if year.to_s.size > 2 - start_year = Chronic.time_class.now.year - bias + start_year = time_class.now.year - bias century = (start_year / 100) * 100 full_year = century + year full_year += 100 if full_year < start_year diff --git a/lib/chronic/handlers.rb b/lib/chronic/handlers.rb index 8d4b7a46..b0c976e6 100644 --- a/lib/chronic/handlers.rb +++ b/lib/chronic/handlers.rb @@ -4,11 +4,12 @@ module Handlers # Handle month/day def handle_m_d(month, day, time_tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month.start = self.now span = month.this(options[:context]) year, month = span.begin.year, span.begin.month - day_start = Chronic.time_class.local(year, month, day) - day_start = Chronic.time_class.local(year + 1, month, day) if options[:context] == :future && day_start < now + day_start = time_class.local(year, month, day) + day_start = time_class.local(year + 1, month, day) if options[:context] == :future && day_start < now day_or_time(day_start, time_tokens, options) end @@ -68,6 +69,7 @@ def handle_od_rmn(tokens, options) end def handle_sy_rmn_od(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) year = tokens[0].get_tag(ScalarYear).type month = tokens[1].get_tag(RepeaterMonthName).index day = tokens[2].get_tag(OrdinalDay).type @@ -76,7 +78,7 @@ def handle_sy_rmn_od(tokens, options) return if month_overflow?(year, month, day) begin - day_start = Chronic.time_class.local(year, month, day) + day_start = time_class.local(year, month, day) day_or_time(day_start, time_tokens, options) rescue ArgumentError nil @@ -112,6 +114,7 @@ def handle_rmn_od_on(tokens, options) # Handle repeater-month-name/scalar-year def handle_rmn_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[0].get_tag(RepeaterMonthName).index year = tokens[1].get_tag(ScalarYear).type @@ -124,8 +127,8 @@ def handle_rmn_sy(tokens, options) end begin - end_time = Chronic.time_class.local(next_month_year, next_month_month) - Span.new(Chronic.time_class.local(year, month), end_time) + end_time = time_class.local(next_month_year, next_month_month) + Span.new(time_class.local(year, month), end_time) rescue ArgumentError nil end @@ -133,7 +136,8 @@ def handle_rmn_sy(tokens, options) # Handle generic timestamp (ruby 1.8) def handle_generic(tokens, options) - t = Chronic.time_class.parse(options[:text]) + time_class = options.fetch(:time_class, Chronic.time_class) + t = time_class.parse(options[:text]) Span.new(t, t + 1) rescue ArgumentError => e raise e unless e.message =~ /out of range/ @@ -141,6 +145,7 @@ def handle_generic(tokens, options) # Handle repeater-month-name/scalar-day/scalar-year def handle_rmn_sd_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[0].get_tag(RepeaterMonthName).index day = tokens[1].get_tag(ScalarDay).type year = tokens[2].get_tag(ScalarYear).type @@ -149,7 +154,7 @@ def handle_rmn_sd_sy(tokens, options) return if month_overflow?(year, month, day) begin - day_start = Chronic.time_class.local(year, month, day) + day_start = time_class.local(year, month, day) day_or_time(day_start, time_tokens, options) rescue ArgumentError nil @@ -158,6 +163,7 @@ def handle_rmn_sd_sy(tokens, options) # Handle repeater-month-name/ordinal-day/scalar-year def handle_rmn_od_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[0].get_tag(RepeaterMonthName).index day = tokens[1].get_tag(OrdinalDay).type year = tokens[2].get_tag(ScalarYear).type @@ -166,7 +172,7 @@ def handle_rmn_od_sy(tokens, options) return if month_overflow?(year, month, day) begin - day_start = Chronic.time_class.local(year, month, day) + day_start = time_class.local(year, month, day) day_or_time(day_start, time_tokens, options) rescue ArgumentError nil @@ -175,6 +181,7 @@ def handle_rmn_od_sy(tokens, options) # Handle oridinal-day/repeater-month-name/scalar-year def handle_od_rmn_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) day = tokens[0].get_tag(OrdinalDay).type month = tokens[1].get_tag(RepeaterMonthName).index year = tokens[2].get_tag(ScalarYear).type @@ -183,7 +190,7 @@ def handle_od_rmn_sy(tokens, options) return if month_overflow?(year, month, day) begin - day_start = Chronic.time_class.local(year, month, day) + day_start = time_class.local(year, month, day) day_or_time(day_start, time_tokens, options) rescue ArgumentError nil @@ -199,6 +206,7 @@ def handle_sd_rmn_sy(tokens, options) # Handle scalar-month/scalar-day/scalar-year (endian middle) def handle_sm_sd_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[0].get_tag(ScalarMonth).type day = tokens[1].get_tag(ScalarDay).type year = tokens[2].get_tag(ScalarYear).type @@ -207,7 +215,7 @@ def handle_sm_sd_sy(tokens, options) return if month_overflow?(year, month, day) begin - day_start = Chronic.time_class.local(year, month, day) + day_start = time_class.local(year, month, day) day_or_time(day_start, time_tokens, options) rescue ArgumentError nil @@ -230,6 +238,7 @@ def handle_sy_sm_sd(tokens, options) # Handle scalar-month/scalar-day def handle_sm_sd(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[0].get_tag(ScalarMonth).type day = tokens[1].get_tag(ScalarDay).type year = self.now.year @@ -238,8 +247,8 @@ def handle_sm_sd(tokens, options) return if month_overflow?(year, month, day) begin - day_start = Chronic.time_class.local(year, month, day) - day_start = Chronic.time_class.local(year + 1, month, day) if options[:context] == :future && day_start < now + day_start = time_class.local(year, month, day) + day_start = time_class.local(year + 1, month, day) if options[:context] == :future && day_start < now day_or_time(day_start, time_tokens, options) rescue ArgumentError nil @@ -253,7 +262,7 @@ def handle_sd_sm(tokens, options) handle_sm_sd(new_tokens + time_tokens, options) end - def handle_year_and_month(year, month) + def handle_year_and_month(year, month, time_class) if month == 12 next_month_year = year + 1 next_month_month = 1 @@ -263,8 +272,8 @@ def handle_year_and_month(year, month) end begin - end_time = Chronic.time_class.local(next_month_year, next_month_month) - Span.new(Chronic.time_class.local(year, month), end_time) + end_time = time_class.local(next_month_year, next_month_month) + Span.new(time_class.local(year, month), end_time) rescue ArgumentError nil end @@ -272,20 +281,23 @@ def handle_year_and_month(year, month) # Handle scalar-month/scalar-year def handle_sm_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[0].get_tag(ScalarMonth).type year = tokens[1].get_tag(ScalarYear).type - handle_year_and_month(year, month) + handle_year_and_month(year, month, time_class) end # Handle scalar-year/scalar-month def handle_sy_sm(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) year = tokens[0].get_tag(ScalarYear).type month = tokens[1].get_tag(ScalarMonth).type - handle_year_and_month(year, month) + handle_year_and_month(year, month, time_class) end # Handle RepeaterDayName RepeaterMonthName OrdinalDay def handle_rdn_rmn_od(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[1].get_tag(RepeaterMonthName) day = tokens[2].get_tag(OrdinalDay).type time_tokens = tokens.last(tokens.size - 3) @@ -295,11 +307,11 @@ def handle_rdn_rmn_od(tokens, options) begin if time_tokens.empty? - start_time = Chronic.time_class.local(year, month.index, day) - end_time = time_with_rollover(year, month.index, day + 1) + start_time = time_class.local(year, month.index, day) + end_time = time_with_rollover(year, month.index, day + 1, time_class) Span.new(start_time, end_time) else - day_start = Chronic.time_class.local(year, month.index, day) + day_start = time_class.local(year, month.index, day) day_or_time(day_start, time_tokens, options) end rescue ArgumentError @@ -309,6 +321,7 @@ def handle_rdn_rmn_od(tokens, options) # Handle RepeaterDayName RepeaterMonthName OrdinalDay ScalarYear def handle_rdn_rmn_od_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[1].get_tag(RepeaterMonthName) day = tokens[2].get_tag(OrdinalDay).type year = tokens[3].get_tag(ScalarYear).type @@ -316,8 +329,8 @@ def handle_rdn_rmn_od_sy(tokens, options) return if month_overflow?(year, month.index, day) begin - start_time = Chronic.time_class.local(year, month.index, day) - end_time = time_with_rollover(year, month.index, day + 1) + start_time = time_class.local(year, month.index, day) + end_time = time_with_rollover(year, month.index, day + 1, time_class) Span.new(start_time, end_time) rescue ArgumentError nil @@ -326,6 +339,7 @@ def handle_rdn_rmn_od_sy(tokens, options) # Handle RepeaterDayName OrdinalDay def handle_rdn_od(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) day = tokens[1].get_tag(OrdinalDay).type time_tokens = tokens.last(tokens.size - 2) year = self.now.year @@ -338,11 +352,11 @@ def handle_rdn_od(tokens, options) begin if time_tokens.empty? - start_time = Chronic.time_class.local(year, month, day) - end_time = time_with_rollover(year, month, day + 1) + start_time = time_class.local(year, month, day) + end_time = time_with_rollover(year, month, day + 1, time_class) Span.new(start_time, end_time) else - day_start = Chronic.time_class.local(year, month, day) + day_start = time_class.local(year, month, day) day_or_time(day_start, time_tokens, options) end rescue ArgumentError @@ -352,6 +366,7 @@ def handle_rdn_od(tokens, options) # Handle RepeaterDayName RepeaterMonthName ScalarDay def handle_rdn_rmn_sd(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[1].get_tag(RepeaterMonthName) day = tokens[2].get_tag(ScalarDay).type time_tokens = tokens.last(tokens.size - 3) @@ -361,11 +376,11 @@ def handle_rdn_rmn_sd(tokens, options) begin if time_tokens.empty? - start_time = Chronic.time_class.local(year, month.index, day) - end_time = time_with_rollover(year, month.index, day + 1) + start_time = time_class.local(year, month.index, day) + end_time = time_with_rollover(year, month.index, day + 1, time_class) Span.new(start_time, end_time) else - day_start = Chronic.time_class.local(year, month.index, day) + day_start = time_class.local(year, month.index, day) day_or_time(day_start, time_tokens, options) end rescue ArgumentError @@ -375,6 +390,7 @@ def handle_rdn_rmn_sd(tokens, options) # Handle RepeaterDayName RepeaterMonthName ScalarDay ScalarYear def handle_rdn_rmn_sd_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) month = tokens[1].get_tag(RepeaterMonthName) day = tokens[2].get_tag(ScalarDay).type year = tokens[3].get_tag(ScalarYear).type @@ -382,8 +398,8 @@ def handle_rdn_rmn_sd_sy(tokens, options) return if month_overflow?(year, month.index, day) begin - start_time = Chronic.time_class.local(year, month.index, day) - end_time = time_with_rollover(year, month.index, day + 1) + start_time = time_class.local(year, month.index, day) + end_time = time_with_rollover(year, month.index, day + 1, time_class) Span.new(start_time, end_time) rescue ArgumentError nil @@ -391,18 +407,19 @@ def handle_rdn_rmn_sd_sy(tokens, options) end def handle_sm_rmn_sy(tokens, options) + time_class = options.fetch(:time_class, Chronic.time_class) day = tokens[0].get_tag(ScalarDay).type month = tokens[1].get_tag(RepeaterMonthName).index year = tokens[2].get_tag(ScalarYear).type if tokens.size > 3 time = get_anchor([tokens.last], options).begin h, m, s = time.hour, time.min, time.sec - time = Chronic.time_class.local(year, month, day, h, m, s) - end_time = Chronic.time_class.local(year, month, day + 1, h, m, s) + time = time_class.local(year, month, day, h, m, s) + end_time = time_class.local(year, month, day + 1, h, m, s) else - time = Chronic.time_class.local(year, month, day) + time = time_class.local(year, month, day) day += 1 unless day >= 31 - end_time = Chronic.time_class.local(year, month, day) + end_time = time_class.local(year, month, day) end Span.new(time, end_time) end @@ -570,7 +587,7 @@ def find_within(tags, span, pointer) end end - def time_with_rollover(year, month, day) + def time_with_rollover(year, month, day, time_class) date_parts = if month_overflow?(year, month, day) if month == 12 @@ -581,7 +598,7 @@ def time_with_rollover(year, month, day) else [year, month, day] end - Chronic.time_class.local(*date_parts) + time_class.local(*date_parts) end def dealias_and_disambiguate_times(tokens, options) @@ -613,11 +630,11 @@ def dealias_and_disambiguate_times(tokens, options) when :morning puts '--morning->am' if Chronic.debug t1.untag(RepeaterDayPortion) - t1.tag(RepeaterDayPortion.new(:am)) + t1.tag(RepeaterDayPortion.new(:am, options)) when :afternoon, :evening, :night puts "--#{t1tag.type}->pm" if Chronic.debug t1.untag(RepeaterDayPortion) - t1.tag(RepeaterDayPortion.new(:pm)) + t1.tag(RepeaterDayPortion.new(:pm, options)) end end @@ -632,7 +649,7 @@ def dealias_and_disambiguate_times(tokens, options) if token.get_tag(RepeaterTime) && token.get_tag(RepeaterTime).type.ambiguous? && (!next_token || !next_token.get_tag(RepeaterDayPortion)) distoken = Token.new('disambiguator') - distoken.tag(RepeaterDayPortion.new(options[:ambiguous_time_range])) + distoken.tag(RepeaterDayPortion.new(options[:ambiguous_time_range], options)) ambiguous_tokens << distoken end end diff --git a/lib/chronic/parser.rb b/lib/chronic/parser.rb index 3d4c95dd..3fa5893e 100644 --- a/lib/chronic/parser.rb +++ b/lib/chronic/parser.rb @@ -55,8 +55,8 @@ class Parser # two digit year is `now + x years` it's assumed to be the # future, `now - x years` is assumed to be the past. def initialize(options = {}) - @options = DEFAULT_OPTIONS.merge(options) - @now = options.delete(:now) || Chronic.time_class.now + @options = DEFAULT_OPTIONS.merge(:time_class => Chronic.time_class).merge(options) + @now = options.delete(:now) || @options[:time_class].now end # Parse "text" with the given options diff --git a/lib/chronic/repeaters/repeater_day.rb b/lib/chronic/repeaters/repeater_day.rb index 5a915a8d..e661df21 100644 --- a/lib/chronic/repeaters/repeater_day.rb +++ b/lib/chronic/repeaters/repeater_day.rb @@ -11,7 +11,7 @@ def next(pointer) super unless @current_day_start - @current_day_start = Chronic.time_class.local(@now.year, @now.month, @now.day) + @current_day_start = time_class.local(@now.year, @now.month, @now.day) end direction = pointer == :future ? 1 : -1 @@ -25,14 +25,14 @@ def this(pointer = :future) case pointer when :future - day_begin = Chronic.construct(@now.year, @now.month, @now.day, @now.hour) - day_end = Chronic.construct(@now.year, @now.month, @now.day) + DAY_SECONDS + day_begin = construct(@now.year, @now.month, @now.day, @now.hour) + day_end = construct(@now.year, @now.month, @now.day) + DAY_SECONDS when :past - day_begin = Chronic.construct(@now.year, @now.month, @now.day) - day_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour) + day_begin = construct(@now.year, @now.month, @now.day) + day_end = construct(@now.year, @now.month, @now.day, @now.hour) when :none - day_begin = Chronic.construct(@now.year, @now.month, @now.day) - day_end = Chronic.construct(@now.year, @now.month, @now.day) + DAY_SECONDS + day_begin = construct(@now.year, @now.month, @now.day) + day_end = construct(@now.year, @now.month, @now.day) + DAY_SECONDS end Span.new(day_begin, day_end) diff --git a/lib/chronic/repeaters/repeater_day_name.rb b/lib/chronic/repeaters/repeater_day_name.rb index fb06e938..9024b9bd 100644 --- a/lib/chronic/repeaters/repeater_day_name.rb +++ b/lib/chronic/repeaters/repeater_day_name.rb @@ -25,7 +25,7 @@ def next(pointer) @current_date += direction * 7 end next_date = @current_date.succ - Span.new(Chronic.construct(@current_date.year, @current_date.month, @current_date.day), Chronic.construct(next_date.year, next_date.month, next_date.day)) + Span.new(construct(@current_date.year, @current_date.month, @current_date.day), construct(next_date.year, next_date.month, next_date.day)) end def this(pointer = :future) diff --git a/lib/chronic/repeaters/repeater_day_portion.rb b/lib/chronic/repeaters/repeater_day_portion.rb index 3a4b4077..680fd483 100644 --- a/lib/chronic/repeaters/repeater_day_portion.rb +++ b/lib/chronic/repeaters/repeater_day_portion.rb @@ -27,27 +27,27 @@ def next(pointer) super unless @current_span - now_seconds = @now - Chronic.construct(@now.year, @now.month, @now.day) + now_seconds = @now - construct(@now.year, @now.month, @now.day) if now_seconds < @range.begin case pointer when :future - range_start = Chronic.construct(@now.year, @now.month, @now.day) + @range.begin + range_start = construct(@now.year, @now.month, @now.day) + @range.begin when :past - range_start = Chronic.construct(@now.year, @now.month, @now.day - 1) + @range.begin + range_start = construct(@now.year, @now.month, @now.day - 1) + @range.begin end elsif now_seconds > @range.end case pointer when :future - range_start = Chronic.construct(@now.year, @now.month, @now.day + 1) + @range.begin + range_start = construct(@now.year, @now.month, @now.day + 1) + @range.begin when :past - range_start = Chronic.construct(@now.year, @now.month, @now.day) + @range.begin + range_start = construct(@now.year, @now.month, @now.day) + @range.begin end else case pointer when :future - range_start = Chronic.construct(@now.year, @now.month, @now.day + 1) + @range.begin + range_start = construct(@now.year, @now.month, @now.day + 1) + @range.begin when :past - range_start = Chronic.construct(@now.year, @now.month, @now.day - 1) + @range.begin + range_start = construct(@now.year, @now.month, @now.day - 1) + @range.begin end end offset = (@range.end - @range.begin) @@ -62,8 +62,8 @@ def next(pointer) -1 end - new_begin = Chronic.construct(@current_span.begin.year, @current_span.begin.month, @current_span.begin.day + days_to_shift_window, @current_span.begin.hour, @current_span.begin.min, @current_span.begin.sec) - new_end = Chronic.construct(@current_span.end.year, @current_span.end.month, @current_span.end.day + days_to_shift_window, @current_span.end.hour, @current_span.end.min, @current_span.end.sec) + new_begin = construct(@current_span.begin.year, @current_span.begin.month, @current_span.begin.day + days_to_shift_window, @current_span.begin.hour, @current_span.begin.min, @current_span.begin.sec) + new_end = construct(@current_span.end.year, @current_span.end.month, @current_span.end.day + days_to_shift_window, @current_span.end.hour, @current_span.end.min, @current_span.end.sec) @current_span = Span.new(new_begin, new_end) end end @@ -71,7 +71,7 @@ def next(pointer) def this(context = :future) super - range_start = Chronic.construct(@now.year, @now.month, @now.day) + @range.begin + range_start = construct(@now.year, @now.month, @now.day) + @range.begin range_end = construct_date_from_reference_and_offset(range_start) @current_span = Span.new(range_start, range_end) end @@ -103,7 +103,7 @@ def construct_date_from_reference_and_offset(reference, offset = nil) second_hand = ((elapsed_seconds_for_range - (12 * 60))) % 60 minute_hand = (elapsed_seconds_for_range - second_hand) / (60) % 60 hour_hand = (elapsed_seconds_for_range - minute_hand - second_hand) / (60 * 60) + reference.hour % 24 - Chronic.construct(reference.year, reference.month, reference.day, hour_hand, minute_hand, second_hand) + construct(reference.year, reference.month, reference.day, hour_hand, minute_hand, second_hand) end end end diff --git a/lib/chronic/repeaters/repeater_fortnight.rb b/lib/chronic/repeaters/repeater_fortnight.rb index d89bcefb..3c77fd6a 100644 --- a/lib/chronic/repeaters/repeater_fortnight.rb +++ b/lib/chronic/repeaters/repeater_fortnight.rb @@ -13,12 +13,12 @@ def next(pointer) unless @current_fortnight_start case pointer when :future - sunday_repeater = RepeaterDayName.new(:sunday) + sunday_repeater = RepeaterDayName.new(:sunday, @options) sunday_repeater.start = @now next_sunday_span = sunday_repeater.next(:future) @current_fortnight_start = next_sunday_span.begin when :past - sunday_repeater = RepeaterDayName.new(:sunday) + sunday_repeater = RepeaterDayName.new(:sunday, @options) sunday_repeater.start = (@now + RepeaterDay::DAY_SECONDS) 2.times { sunday_repeater.next(:past) } last_sunday_span = sunday_repeater.next(:past) @@ -39,16 +39,16 @@ def this(pointer = :future) case pointer when :future - this_fortnight_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS - sunday_repeater = RepeaterDayName.new(:sunday) + this_fortnight_start = construct(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS + sunday_repeater = RepeaterDayName.new(:sunday, @options) sunday_repeater.start = @now sunday_repeater.this(:future) this_sunday_span = sunday_repeater.this(:future) this_fortnight_end = this_sunday_span.begin Span.new(this_fortnight_start, this_fortnight_end) when :past - this_fortnight_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour) - sunday_repeater = RepeaterDayName.new(:sunday) + this_fortnight_end = construct(@now.year, @now.month, @now.day, @now.hour) + sunday_repeater = RepeaterDayName.new(:sunday, @options) sunday_repeater.start = @now last_sunday_span = sunday_repeater.next(:past) this_fortnight_start = last_sunday_span.begin diff --git a/lib/chronic/repeaters/repeater_hour.rb b/lib/chronic/repeaters/repeater_hour.rb index 66878e7d..057cc790 100644 --- a/lib/chronic/repeaters/repeater_hour.rb +++ b/lib/chronic/repeaters/repeater_hour.rb @@ -13,9 +13,9 @@ def next(pointer) unless @current_hour_start case pointer when :future - @current_hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour + 1) + @current_hour_start = construct(@now.year, @now.month, @now.day, @now.hour + 1) when :past - @current_hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour - 1) + @current_hour_start = construct(@now.year, @now.month, @now.day, @now.hour - 1) end else direction = pointer == :future ? 1 : -1 @@ -30,13 +30,13 @@ def this(pointer = :future) case pointer when :future - hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1) - hour_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour + 1) + hour_start = construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1) + hour_end = construct(@now.year, @now.month, @now.day, @now.hour + 1) when :past - hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour) - hour_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + hour_start = construct(@now.year, @now.month, @now.day, @now.hour) + hour_end = construct(@now.year, @now.month, @now.day, @now.hour, @now.min) when :none - hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour) + hour_start = construct(@now.year, @now.month, @now.day, @now.hour) hour_end = hour_start + HOUR_SECONDS end diff --git a/lib/chronic/repeaters/repeater_minute.rb b/lib/chronic/repeaters/repeater_minute.rb index 7fb50b36..88653732 100644 --- a/lib/chronic/repeaters/repeater_minute.rb +++ b/lib/chronic/repeaters/repeater_minute.rb @@ -13,9 +13,9 @@ def next(pointer = :future) unless @current_minute_start case pointer when :future - @current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1) + @current_minute_start = construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1) when :past - @current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min - 1) + @current_minute_start = construct(@now.year, @now.month, @now.day, @now.hour, @now.min - 1) end else direction = pointer == :future ? 1 : -1 @@ -31,13 +31,13 @@ def this(pointer = :future) case pointer when :future minute_begin = @now - minute_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + minute_end = construct(@now.year, @now.month, @now.day, @now.hour, @now.min) when :past - minute_begin = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + minute_begin = construct(@now.year, @now.month, @now.day, @now.hour, @now.min) minute_end = @now when :none - minute_begin = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) - minute_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS + minute_begin = construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + minute_end = construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS end Span.new(minute_begin, minute_end) diff --git a/lib/chronic/repeaters/repeater_month.rb b/lib/chronic/repeaters/repeater_month.rb index 48cc50f2..e5dab406 100644 --- a/lib/chronic/repeaters/repeater_month.rb +++ b/lib/chronic/repeaters/repeater_month.rb @@ -14,12 +14,12 @@ def next(pointer) super unless @current_month_start - @current_month_start = offset_by(Chronic.construct(@now.year, @now.month), 1, pointer) + @current_month_start = offset_by(construct(@now.year, @now.month), 1, pointer) else - @current_month_start = offset_by(Chronic.construct(@current_month_start.year, @current_month_start.month), 1, pointer) + @current_month_start = offset_by(construct(@current_month_start.year, @current_month_start.month), 1, pointer) end - Span.new(@current_month_start, Chronic.construct(@current_month_start.year, @current_month_start.month + 1)) + Span.new(@current_month_start, construct(@current_month_start.year, @current_month_start.month + 1)) end def this(pointer = :future) @@ -27,14 +27,14 @@ def this(pointer = :future) case pointer when :future - month_start = Chronic.construct(@now.year, @now.month, @now.day + 1) - month_end = self.offset_by(Chronic.construct(@now.year, @now.month), 1, :future) + month_start = construct(@now.year, @now.month, @now.day + 1) + month_end = self.offset_by(construct(@now.year, @now.month), 1, :future) when :past - month_start = Chronic.construct(@now.year, @now.month) - month_end = Chronic.construct(@now.year, @now.month, @now.day) + month_start = construct(@now.year, @now.month) + month_end = construct(@now.year, @now.month, @now.day) when :none - month_start = Chronic.construct(@now.year, @now.month) - month_end = self.offset_by(Chronic.construct(@now.year, @now.month), 1, :future) + month_start = construct(@now.year, @now.month) + month_end = self.offset_by(construct(@now.year, @now.month), 1, :future) end Span.new(month_start, month_end) @@ -60,7 +60,7 @@ def offset_by(time, amount, pointer) days = month_days(new_year, new_month) new_day = time.day > days ? days : time.day - Chronic.construct(new_year, new_month, new_day, time.hour, time.min, time.sec) + construct(new_year, new_month, new_day, time.hour, time.min, time.sec) end def width diff --git a/lib/chronic/repeaters/repeater_month_name.rb b/lib/chronic/repeaters/repeater_month_name.rb index 52878fb9..2cccd3d2 100644 --- a/lib/chronic/repeaters/repeater_month_name.rb +++ b/lib/chronic/repeaters/repeater_month_name.rb @@ -28,30 +28,30 @@ def next(pointer) case pointer when :future if @now.month < index - @current_month_begin = Chronic.construct(@now.year, index) + @current_month_begin = construct(@now.year, index) elsif @now.month > index - @current_month_begin = Chronic.construct(@now.year + 1, index) + @current_month_begin = construct(@now.year + 1, index) end when :none if @now.month <= index - @current_month_begin = Chronic.construct(@now.year, index) + @current_month_begin = construct(@now.year, index) elsif @now.month > index - @current_month_begin = Chronic.construct(@now.year + 1, index) + @current_month_begin = construct(@now.year + 1, index) end when :past if @now.month >= index - @current_month_begin = Chronic.construct(@now.year, index) + @current_month_begin = construct(@now.year, index) elsif @now.month < index - @current_month_begin = Chronic.construct(@now.year - 1, index) + @current_month_begin = construct(@now.year - 1, index) end end @current_month_begin || raise('Current month should be set by now') else case pointer when :future - @current_month_begin = Chronic.construct(@current_month_begin.year + 1, @current_month_begin.month) + @current_month_begin = construct(@current_month_begin.year + 1, @current_month_begin.month) when :past - @current_month_begin = Chronic.construct(@current_month_begin.year - 1, @current_month_begin.month) + @current_month_begin = construct(@current_month_begin.year - 1, @current_month_begin.month) end end @@ -66,7 +66,7 @@ def next(pointer) next_month_month = cur_month_month + 1 end - Span.new(@current_month_begin, Chronic.construct(next_month_year, next_month_month)) + Span.new(@current_month_begin, construct(next_month_year, next_month_month)) end def this(pointer = :future) diff --git a/lib/chronic/repeaters/repeater_season.rb b/lib/chronic/repeaters/repeater_season.rb index 972064e7..a1486471 100644 --- a/lib/chronic/repeaters/repeater_season.rb +++ b/lib/chronic/repeaters/repeater_season.rb @@ -28,7 +28,7 @@ def this(pointer = :future) direction = pointer == :future ? 1 : -1 - today = Chronic.construct(@now.year, @now.month, @now.day) + today = construct(@now.year, @now.month, @now.day) this_ssn = find_current_season(MiniDate.from_time(@now)) case pointer when :past @@ -66,8 +66,8 @@ def to_s def find_next_season_span(direction, next_season) unless @next_season_start || @next_season_end - @next_season_start = Chronic.construct(@now.year, @now.month, @now.day) - @next_season_end = Chronic.construct(@now.year, @now.month, @now.day) + @next_season_start = construct(@now.year, @now.month, @now.day) + @next_season_end = construct(@now.year, @now.month, @now.day) end @next_season_start += direction * num_seconds_til_start(next_season, direction) @@ -83,7 +83,7 @@ def find_current_season(md) end def num_seconds_til(goal, direction) - start = Chronic.construct(@now.year, @now.month, @now.day) + start = construct(@now.year, @now.month, @now.day) seconds = 0 until MiniDate.from_time(start + direction * seconds).equals?(goal) @@ -103,8 +103,8 @@ def num_seconds_til_end(season_symbol, direction) def construct_season(start, finish) Span.new( - Chronic.construct(start.year, start.month, start.day), - Chronic.construct(finish.year, finish.month, finish.day) + construct(start.year, start.month, start.day), + construct(finish.year, finish.month, finish.day) ) end end diff --git a/lib/chronic/repeaters/repeater_season_name.rb b/lib/chronic/repeaters/repeater_season_name.rb index f92beff1..3c3ff3fb 100644 --- a/lib/chronic/repeaters/repeater_season_name.rb +++ b/lib/chronic/repeaters/repeater_season_name.rb @@ -11,7 +11,7 @@ def next(pointer) def this(pointer = :future) direction = pointer == :future ? 1 : -1 - today = Chronic.construct(@now.year, @now.month, @now.day) + today = construct(@now.year, @now.month, @now.day) goal_ssn_start = today + direction * num_seconds_til_start(@type, direction) goal_ssn_end = today + direction * num_seconds_til_end(@type, direction) curr_ssn = find_current_season(MiniDate.from_time(@now)) diff --git a/lib/chronic/repeaters/repeater_time.rb b/lib/chronic/repeaters/repeater_time.rb index e21c8b03..08637fb6 100644 --- a/lib/chronic/repeaters/repeater_time.rb +++ b/lib/chronic/repeaters/repeater_time.rb @@ -76,7 +76,7 @@ def next(pointer) unless @current_time first = true - midnight = Chronic.time_class.local(@now.year, @now.month, @now.day) + midnight = time_class.local(@now.year, @now.month, @now.day) yesterday_midnight = midnight - full_day tomorrow_midnight = midnight + full_day diff --git a/lib/chronic/repeaters/repeater_week.rb b/lib/chronic/repeaters/repeater_week.rb index e5672552..e7710572 100644 --- a/lib/chronic/repeaters/repeater_week.rb +++ b/lib/chronic/repeaters/repeater_week.rb @@ -14,12 +14,12 @@ def next(pointer) unless @current_week_start case pointer when :future - first_week_day_repeater = RepeaterDayName.new(@repeater_day_name) + first_week_day_repeater = RepeaterDayName.new(@repeater_day_name, @options) first_week_day_repeater.start = @now next_span = first_week_day_repeater.next(:future) @current_week_start = next_span.begin when :past - first_week_day_repeater = RepeaterDayName.new(@repeater_day_name) + first_week_day_repeater = RepeaterDayName.new(@repeater_day_name, @options) first_week_day_repeater.start = (@now + RepeaterDay::DAY_SECONDS) first_week_day_repeater.next(:past) last_span = first_week_day_repeater.next(:past) @@ -38,21 +38,21 @@ def this(pointer = :future) case pointer when :future - this_week_start = Chronic.time_class.local(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS - first_week_day_repeater = RepeaterDayName.new(@repeater_day_name) + this_week_start = time_class.local(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS + first_week_day_repeater = RepeaterDayName.new(@repeater_day_name, @options) first_week_day_repeater.start = @now this_span = first_week_day_repeater.this(:future) this_week_end = this_span.begin Span.new(this_week_start, this_week_end) when :past - this_week_end = Chronic.time_class.local(@now.year, @now.month, @now.day, @now.hour) - first_week_day_repeater = RepeaterDayName.new(@repeater_day_name) + this_week_end = time_class.local(@now.year, @now.month, @now.day, @now.hour) + first_week_day_repeater = RepeaterDayName.new(@repeater_day_name, @options) first_week_day_repeater.start = @now last_span = first_week_day_repeater.next(:past) this_week_start = last_span.begin Span.new(this_week_start, this_week_end) when :none - first_week_day_repeater = RepeaterDayName.new(@repeater_day_name) + first_week_day_repeater = RepeaterDayName.new(@repeater_day_name, @options) first_week_day_repeater.start = @now last_span = first_week_day_repeater.next(:past) this_week_start = last_span.begin diff --git a/lib/chronic/repeaters/repeater_weekday.rb b/lib/chronic/repeaters/repeater_weekday.rb index 9a79304b..31ec5568 100644 --- a/lib/chronic/repeaters/repeater_weekday.rb +++ b/lib/chronic/repeaters/repeater_weekday.rb @@ -22,7 +22,7 @@ def next(pointer) direction = pointer == :future ? 1 : -1 unless @current_weekday_start - @current_weekday_start = Chronic.construct(@now.year, @now.month, @now.day) + @current_weekday_start = construct(@now.year, @now.month, @now.day) @current_weekday_start += direction * DAY_SECONDS until is_weekday?(@current_weekday_start.wday) diff --git a/lib/chronic/repeaters/repeater_weekend.rb b/lib/chronic/repeaters/repeater_weekend.rb index 9f065cb8..09f3f5ee 100644 --- a/lib/chronic/repeaters/repeater_weekend.rb +++ b/lib/chronic/repeaters/repeater_weekend.rb @@ -13,12 +13,12 @@ def next(pointer) unless @current_week_start case pointer when :future - saturday_repeater = RepeaterDayName.new(:saturday) + saturday_repeater = RepeaterDayName.new(:saturday, @options) saturday_repeater.start = @now next_saturday_span = saturday_repeater.next(:future) @current_week_start = next_saturday_span.begin when :past - saturday_repeater = RepeaterDayName.new(:saturday) + saturday_repeater = RepeaterDayName.new(:saturday, @options) saturday_repeater.start = (@now + RepeaterDay::DAY_SECONDS) last_saturday_span = saturday_repeater.next(:past) @current_week_start = last_saturday_span.begin @@ -36,12 +36,12 @@ def this(pointer = :future) case pointer when :future, :none - saturday_repeater = RepeaterDayName.new(:saturday) + saturday_repeater = RepeaterDayName.new(:saturday, @options) saturday_repeater.start = @now this_saturday_span = saturday_repeater.this(:future) Span.new(this_saturday_span.begin, this_saturday_span.begin + WEEKEND_SECONDS) when :past - saturday_repeater = RepeaterDayName.new(:saturday) + saturday_repeater = RepeaterDayName.new(:saturday, @options) saturday_repeater.start = @now last_saturday_span = saturday_repeater.this(:past) Span.new(last_saturday_span.begin, last_saturday_span.begin + WEEKEND_SECONDS) @@ -50,7 +50,7 @@ def this(pointer = :future) def offset(span, amount, pointer) direction = pointer == :future ? 1 : -1 - weekend = RepeaterWeekend.new(:weekend) + weekend = RepeaterWeekend.new(:weekend, @options) weekend.start = span.begin start = weekend.next(pointer).begin + (amount - 1) * direction * RepeaterWeek::WEEK_SECONDS Span.new(start, start + (span.end - span.begin)) diff --git a/lib/chronic/repeaters/repeater_year.rb b/lib/chronic/repeaters/repeater_year.rb index 797fd34b..cd7a56a0 100644 --- a/lib/chronic/repeaters/repeater_year.rb +++ b/lib/chronic/repeaters/repeater_year.rb @@ -13,16 +13,16 @@ def next(pointer) unless @current_year_start case pointer when :future - @current_year_start = Chronic.construct(@now.year + 1) + @current_year_start = construct(@now.year + 1) when :past - @current_year_start = Chronic.construct(@now.year - 1) + @current_year_start = construct(@now.year - 1) end else diff = pointer == :future ? 1 : -1 - @current_year_start = Chronic.construct(@current_year_start.year + diff) + @current_year_start = construct(@current_year_start.year + diff) end - Span.new(@current_year_start, Chronic.construct(@current_year_start.year + 1)) + Span.new(@current_year_start, construct(@current_year_start.year + 1)) end def this(pointer = :future) @@ -30,14 +30,14 @@ def this(pointer = :future) case pointer when :future - this_year_start = Chronic.construct(@now.year, @now.month, @now.day + 1) - this_year_end = Chronic.construct(@now.year + 1, 1, 1) + this_year_start = construct(@now.year, @now.month, @now.day + 1) + this_year_end = construct(@now.year + 1, 1, 1) when :past - this_year_start = Chronic.construct(@now.year, 1, 1) - this_year_end = Chronic.construct(@now.year, @now.month, @now.day) + this_year_start = construct(@now.year, 1, 1) + this_year_end = construct(@now.year, @now.month, @now.day) when :none - this_year_start = Chronic.construct(@now.year, 1, 1) - this_year_end = Chronic.construct(@now.year + 1, 1, 1) + this_year_start = construct(@now.year, 1, 1) + this_year_end = construct(@now.year + 1, 1, 1) end Span.new(this_year_start, this_year_end) @@ -64,7 +64,7 @@ def build_offset_time(time, amount, direction) year = time.year + (amount * direction) days = month_days(year, time.month) day = time.day > days ? days : time.day - Chronic.construct(year, time.month, day, time.hour, time.min, time.sec) + construct(year, time.month, day, time.hour, time.min, time.sec) end def month_days(year, month) diff --git a/lib/chronic/tags/ordinal.rb b/lib/chronic/tags/ordinal.rb index 1f3ffd0d..62f37ee7 100644 --- a/lib/chronic/tags/ordinal.rb +++ b/lib/chronic/tags/ordinal.rb @@ -16,7 +16,7 @@ def self.scan(tokens, options) tokens[i].tag(OrdinalDay.new(ordinal)) if Chronic::Date::could_be_day?(ordinal) tokens[i].tag(OrdinalMonth.new(ordinal)) if Chronic::Date::could_be_month?(ordinal) if Chronic::Date::could_be_year?(ordinal) - year = Chronic::Date::make_year(ordinal, options[:ambiguous_year_future_bias]) + year = Chronic::Date::make_year(ordinal, options[:ambiguous_year_future_bias], options[:time_class]) tokens[i].tag(OrdinalYear.new(year.to_i)) end end diff --git a/lib/chronic/tags/repeater.rb b/lib/chronic/tags/repeater.rb index 9a7ea117..7834fb72 100644 --- a/lib/chronic/tags/repeater.rb +++ b/lib/chronic/tags/repeater.rb @@ -141,5 +141,13 @@ def this(pointer) def to_s 'repeater' end + + def time_class + @options.fetch(:time_class, Chronic.time_class) + end + + def construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, offset = nil) + Chronic.construct(year, month, day, hour, minute, second, offset, time_class) + end end end diff --git a/lib/chronic/tags/scalar.rb b/lib/chronic/tags/scalar.rb index 385aa534..9218fb2e 100644 --- a/lib/chronic/tags/scalar.rb +++ b/lib/chronic/tags/scalar.rb @@ -24,7 +24,7 @@ def self.scan(tokens, options) token.tag(ScalarDay.new(scalar)) if Chronic::Date::could_be_day?(scalar) token.tag(ScalarMonth.new(scalar)) if Chronic::Date::could_be_month?(scalar) if Chronic::Date::could_be_year?(scalar) - year = Chronic::Date::make_year(scalar, options[:ambiguous_year_future_bias]) + year = Chronic::Date::make_year(scalar, options[:ambiguous_year_future_bias], options[:time_class]) token.tag(ScalarYear.new(year.to_i)) end end @@ -78,4 +78,4 @@ def to_s super << '-year-' << @type.to_s end end -end \ No newline at end of file +end diff --git a/lib/chronic/time.rb b/lib/chronic/time.rb index 0af6b0ef..27b6445b 100644 --- a/lib/chronic/time.rb +++ b/lib/chronic/time.rb @@ -26,9 +26,9 @@ def self.could_be_subsecond?(subsecond) end # normalize offset in seconds to offset as string +mm:ss or -mm:ss - def self.normalize_offset(offset) + def self.normalize_offset(offset, time_class = Chronic.time_class) return offset if offset.is_a?(String) - offset = Chronic.time_class.now.to_time.utc_offset unless offset # get current system's UTC offset if offset is nil + offset = time_class.now.to_time.utc_offset unless offset # get current system's UTC offset if offset is nil sign = '+' sign = '-' if offset < 0 hours = (offset.abs / 3600).to_i.to_s.rjust(2,'0') diff --git a/test/test_chronic.rb b/test/test_chronic.rb index 3cc4facd..1616325c 100644 --- a/test/test_chronic.rb +++ b/test/test_chronic.rb @@ -181,4 +181,8 @@ def test_activesupport end =end end + + def test_time_class_option + assert_equal DateTime.new(2013, 8, 27, 20, 30, 40, '-08:00'), Chronic.construct(2013, 8, 27, 20, 30, 40, -28800, ::DateTime) + end end diff --git a/test/test_parsing.rb b/test/test_parsing.rb index 577d00c4..35ac99c4 100644 --- a/test/test_parsing.rb +++ b/test/test_parsing.rb @@ -1245,7 +1245,13 @@ def test_normalizing_day_portions private def parse_now(string, options={}) - Chronic.parse(string, {:now => TIME_2006_08_16_14_00_00 }.merge(options)) + begin + old = Chronic.time_class + Chronic.time_class = ::Date + Chronic.parse(string, {:now => TIME_2006_08_16_14_00_00, :time_class => old }.merge(options)) + ensure + Chronic.time_class = old + end end def pre_normalize(s) Chronic::Parser.new.pre_normalize s