Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add default_time_now option to make Chronic use current time on specified date if no time is specified #362

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 10 additions & 1 deletion lib/chronic/handlers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
9 changes: 8 additions & 1 deletion lib/chronic/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion test/test_chronic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions test/test_parsing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down