diff --git a/README.md b/README.md index 2f0c5984..8e759480 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,12 @@ Chronic.parse('6/4/2012', :endian_precedence => :little) Chronic.parse('INVALID DATE') #=> nil + +Chronic.parse('sunday') + #=> Sun Sep 03 12:00:00 PDT 2006 + +Chronic.parse('sunday', today: true) + #=> Sun Aug 27 12:00:00 PDT 2006 ``` If the parser can find a date or time, either a Time or Chronic::Span diff --git a/lib/chronic/handlers.rb b/lib/chronic/handlers.rb index 8d4b7a46..e76fa881 100644 --- a/lib/chronic/handlers.rb +++ b/lib/chronic/handlers.rb @@ -521,7 +521,9 @@ def get_anchor(tokens, options) when :last outer_span = head.next(:past) when :this - if options[:context] != :past and repeaters.size > 0 + if options[:today] + outer_span = head.this(:today) + elsif options[:context] != :past and repeaters.size > 0 outer_span = head.this(:none) else outer_span = head.this(options[:context]) diff --git a/lib/chronic/parser.rb b/lib/chronic/parser.rb index 3d4c95dd..9f857df5 100644 --- a/lib/chronic/parser.rb +++ b/lib/chronic/parser.rb @@ -14,7 +14,8 @@ class Parser :guess => true, :ambiguous_time_range => 6, :endian_precedence => [:middle, :little], - :ambiguous_year_future_bias => 50 + :ambiguous_year_future_bias => 50, + :today => false } attr_accessor :now @@ -54,6 +55,11 @@ class Parser # look x amount of years into the future and past. If the # two digit year is `now + x years` it's assumed to be the # future, `now - x years` is assumed to be the past. + # :today - When true is given, Chronic will parse day name as current + # date if they are ambigious. For example, Chronic.parse("monday") + # on 02/09/2015 will give "2015-02-16 12:00:00" without :today flag, + # and "2015-02-09 12:00:00" with `today: true`. + def initialize(options = {}) @options = DEFAULT_OPTIONS.merge(options) @now = options.delete(:now) || Chronic.time_class.now diff --git a/lib/chronic/repeaters/repeater_day_name.rb b/lib/chronic/repeaters/repeater_day_name.rb index fb06e938..f60e2698 100644 --- a/lib/chronic/repeaters/repeater_day_name.rb +++ b/lib/chronic/repeaters/repeater_day_name.rb @@ -11,13 +11,15 @@ def next(pointer) super direction = pointer == :future ? 1 : -1 + direction = 0 if pointer == :today + + day_num = symbol_to_number(@type) + raise ArgumentError, "It's not #{day_num.to_s} today" if pointer == :today && @now.wday != day_num unless @current_date @current_date = ::Date.new(@now.year, @now.month, @now.day) @current_date += direction - day_num = symbol_to_number(@type) - while @current_date.wday != day_num @current_date += direction end diff --git a/test/test_parsing.rb b/test/test_parsing.rb index 577d00c4..3d4e8ac7 100644 --- a/test/test_parsing.rb +++ b/test/test_parsing.rb @@ -1239,6 +1239,34 @@ def test_handle_rdn_rmn_od_sy assert_equal Time.local(2005, 12, 30, 12), time end + def test_get_anchor + time = parse_now("wednesday") + assert_equal Time.local(2006, 8, 23, 12), time + + time = parse_now("this wednesday") + assert_equal Time.local(2006, 8, 23, 12), time + + time = parse_now("wednesday at 16:30") + assert_equal Time.local(2006, 8, 23, 16, 30), time + + time = parse_now("wednesday", today: true) + assert_equal Time.local(2006, 8, 16, 12), time + + time = parse_now("this wednesday", today: true) + assert_equal Time.local(2006, 8, 16, 12), time + + time = parse_now("wednesday at 16:00", today: true) + assert_equal Time.local(2006, 8, 16, 16), time + + assert_raises(ArgumentError) do + parse_now("thursday at 16:00", today: true) + end + + assert_raises(ArgumentError) do + parse_now("tuesday", today: true) + end + end + def test_normalizing_day_portions assert_equal pre_normalize("8:00 pm February 11"), pre_normalize("8:00 p.m. February 11") end