Skip to content

Commit

Permalink
Merge pull request mojombo#195 from davispuh/subsecond
Browse files Browse the repository at this point in the history
Correctly parse time with subseconds
  • Loading branch information
leejarvis committed Jul 30, 2013
2 parents 40f1aad + f753f3c commit e68d360
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 25 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ Specific Times (many of the above with an added time)
* January 5 at 7pm
* 22nd of june at 8am
* 1979-05-27 05:00:00
* 03/01/2012 07:25:09.234567
* etc


Expand Down
2 changes: 1 addition & 1 deletion lib/chronic/repeater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def self.scan_for_day_portions(token)
#
# Returns a new Repeater object.
def self.scan_for_times(token)
scan_for token, RepeaterTime, /^\d{1,2}(:?\d{1,2})?([\.:]?\d{1,2})?$/
scan_for token, RepeaterTime, /^\d{1,2}(:?\d{1,2})?([\.:]?\d{1,2}([\.:]\d{1,6})?)?$/
end

# token - The Token object we want to scan.
Expand Down
49 changes: 26 additions & 23 deletions lib/chronic/repeaters/repeater_time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,33 @@ def to_s

def initialize(time)
@current_time = nil
t = time.gsub(/\:/, '')

@type =
case t.size
when 1..2
hours = t.to_i
Tick.new((hours == 12 ? 0 : hours) * 60 * 60, true)
when 3
hours = t[0..0].to_i
ambiguous = hours > 0
Tick.new((hours * 60 * 60) + (t[1..2].to_i * 60), ambiguous)
when 4
ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
hours = t[0..1].to_i
hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60, ambiguous)
when 5
Tick.new(t[0..0].to_i * 60 * 60 + t[1..2].to_i * 60 + t[3..4].to_i, true)
when 6
ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
hours = t[0..1].to_i
hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous)
else
raise("Time cannot exceed six digits")
time_parts = time.split(':')
raise ArgumentError, "Time cannot have more than 4 groups of ':'" if time_parts.count > 4

if time_parts.first.length > 2 and time_parts.count == 1
if time_parts.first.length > 4
second_index = time_parts.first.length - 2
time_parts.insert(1, time_parts.first[second_index..time_parts.first.length])
time_parts[0] = time_parts.first[0..second_index - 1]
end
minute_index = time_parts.first.length - 2
time_parts.insert(1, time_parts.first[minute_index..time_parts.first.length])
time_parts[0] = time_parts.first[0..minute_index - 1]
end

ambiguous = false
hours = time_parts.first.to_i
ambiguous = true if (time_parts.first.length == 1 and hours > 0) or (hours >= 10 and hours <= 12)
hours = (hours == 12 ? 0 : hours) * 60 * 60
minutes = 0
seconds = 0
subseconds = 0

minutes = time_parts[1].to_i * 60 if time_parts.count > 1
seconds = time_parts[2].to_i if time_parts.count > 2
subseconds = time_parts[3].to_f / (10 ** time_parts[3].length) if time_parts.count > 3

@type = Tick.new(hours + minutes + seconds + subseconds, ambiguous)
end

# Return the next past or future Span for the time that this Repeater represents
Expand Down
15 changes: 14 additions & 1 deletion test/test_parsing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ def test_handle_generic

time = Chronic.parse("2012-01-03 01:00:00.100")
time2 = Time.parse("2012-01-03 01:00:00.100")
assert_equal time, time2
assert_in_delta time, time2, 0.001

time = Chronic.parse("2012-01-03 01:00:00.234567")
time2 = Time.parse("2012-01-03 01:00:00.234567")
assert_in_delta time, time2, 0.000001

assert_nil Chronic.parse("1/1/32.1")

Expand Down Expand Up @@ -64,6 +68,9 @@ def test_handle_rmn_sd

time = parse_now("may 28 at 5:32.19pm", :context => :past)
assert_equal Time.local(2006, 5, 28, 17, 32, 19), time

time = parse_now("may 28 at 5:32:19.764")
assert_in_delta Time.local(2007, 5, 28, 17, 32, 19, 764000), time, 0.001
end

def test_handle_rmn_sd_on
Expand Down Expand Up @@ -171,6 +178,9 @@ def test_handle_sy_sm_sd_t_tz

time = parse_now("2011-07-03 21:11:35 UTC")
assert_equal 1309727495, time.to_i

time = parse_now("2011-07-03 21:11:35.362 UTC")
assert_in_delta 1309727495.362, time.to_f, 0.001
end

def test_handle_rmn_sd_sy
Expand Down Expand Up @@ -325,6 +335,9 @@ def test_handle_sy_sm_sd
time = parse_now("2006-08-20 15:30.30")
assert_equal Time.local(2006, 8, 20, 15, 30, 30), time

time = parse_now("2006-08-20 15:30:30:000536")
assert_in_delta Time.local(2006, 8, 20, 15, 30, 30, 536), time, 0.000001

time = parse_now("1902-08-20")
assert_equal Time.local(1902, 8, 20, 12, 0, 0), time

Expand Down
18 changes: 18 additions & 0 deletions test/test_repeater_time.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ def setup
@now = Time.local(2006, 8, 16, 14, 0, 0, 0)
end

def test_generic
assert_raises(ArgumentError) do
Chronic::RepeaterTime.new('00:01:02:03:004')
end
end

def test_next_future
t = Chronic::RepeaterTime.new('4:00')
t.start = @now
Expand All @@ -25,6 +31,12 @@ def test_next_future

assert_equal Time.local(2006, 8, 17, 4), t.next(:future).begin
assert_equal Time.local(2006, 8, 18, 4), t.next(:future).begin

t = Chronic::RepeaterTime.new('0000')
t.start = @now

assert_equal Time.local(2006, 8, 17, 0), t.next(:future).begin
assert_equal Time.local(2006, 8, 18, 0), t.next(:future).begin
end

def test_next_past
Expand All @@ -39,6 +51,12 @@ def test_next_past

assert_equal Time.local(2006, 8, 16, 13), t.next(:past).begin
assert_equal Time.local(2006, 8, 15, 13), t.next(:past).begin

t = Chronic::RepeaterTime.new('0:00.000')
t.start = @now

assert_equal Time.local(2006, 8, 16, 0), t.next(:past).begin
assert_equal Time.local(2006, 8, 15, 0), t.next(:past).begin
end

def test_type
Expand Down

0 comments on commit e68d360

Please sign in to comment.