diff --git a/README.md b/README.md index 4b2bf042..7ec9f090 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ Chronic.parse('this tuesday 5:00', :ambiguous_time_range => :none) Chronic.parse('may 27th', :now => Time.local(2000, 1, 1)) #=> Sat May 27 12:00:00 PDT 2000 +Chronic.parse('may 27th', :default_time_now => true) + #=> Sun May 27 23:18:25 PDT 2007 + Chronic.parse('may 27th', :guess => false) #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007 diff --git a/lib/chronic/handlers.rb b/lib/chronic/handlers.rb index 27795a7d..5b3b94f3 100644 --- a/lib/chronic/handlers.rb +++ b/lib/chronic/handlers.rb @@ -518,7 +518,7 @@ def handle_o_r_g_r(tokens, options) # support methods def day_or_time(day_start, time_tokens, options) - outer_span = Span.new(day_start, day_start + (24 * 60 * 60)) + outer_span = span_from_day_start(day_start, time_tokens, options) unless time_tokens.empty? self.now = outer_span.begin @@ -528,6 +528,15 @@ def day_or_time(day_start, time_tokens, options) end end + def span_from_day_start(day_start, time_tokens, options) + if time_tokens.empty? && options[:default_time_now] + exact_date_time = day_start + now.hour * 60 * 60 + now.min * 60 + now.sec + Span.new(exact_date_time, exact_date_time) + else + Span.new(day_start, day_start + (24 * 60 * 60)) + end + end + def get_anchor(tokens, options) grabber = Grabber.new(:this) pointer = :future diff --git a/lib/chronic/parser.rb b/lib/chronic/parser.rb index 4ba4bec3..847bdcbc 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, + :default_time_now => false } attr_accessor :now @@ -54,6 +55,12 @@ 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. + # :default_time_now - By default, if no time is explicitly passed in, + # the parser will set the time to be either at the beginning, + # middle, or end of the day (depending on the :guess option). + # Set this to true to make the parser return the current time + # on the requested date if only a date is passed in. If a time + # is passed in, this setting will be ignored. def initialize(options = {}) validate_options!(options) @options = DEFAULT_OPTIONS.merge(options) diff --git a/test/test_chronic.rb b/test/test_chronic.rb index eb62ad1e..700e0907 100644 --- a/test/test_chronic.rb +++ b/test/test_chronic.rb @@ -171,7 +171,8 @@ def test_valid_options :guess => true, :ambiguous_time_range => 6, :endian_precedence => [:middle, :little], - :ambiguous_year_future_bias => 50 + :ambiguous_year_future_bias => 50, + :default_time_now => false } refute_nil Chronic.parse('now', options) end diff --git a/test/test_parsing.rb b/test/test_parsing.rb index 979167b6..7d5aa563 100644 --- a/test/test_parsing.rb +++ b/test/test_parsing.rb @@ -1520,6 +1520,26 @@ def test_normalizing_time_of_day_phrases assert_equal pre_normalize("midday February 11"), pre_normalize("12:00 p.m. February 11") end + def test_default_time_now + time = parse_now("may 27", :default_time_now => true) + assert_equal Time.local(2007, 5, 27, 14), time + + time = parse_now("may 27 at 5pm", :default_time_now => true) + assert_equal Time.local(2007, 5, 27, 17), time + + time = parse_now("1 week from now", :default_time_now => true) + assert_equal Time.local(2006, 8, 23, 14), time + + time = parse_now("September 19 2017", :default_time_now => true) + assert_equal Time.local(2017, 9, 19, 14), time + + time = parse_now("September 19 2017 at 2:00am", :default_time_now => true) + assert_equal Time.local(2017, 9, 19, 2), time + + time = parse_now("may 27th", :default_time_now => true, :now => Time.local(2006, 8, 27, 23, 18, 25, 0)) + assert_equal Time.local(2007, 5, 27, 23, 18, 25), time + end + private def parse_now(string, options={}) Chronic.parse(string, {:now => TIME_2006_08_16_14_00_00 }.merge(options))