chronic 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +9 -0
- data/Manifest.txt +3 -1
- data/Rakefile +2 -0
- data/lib/chronic/chronic.rb +2 -4
- data/lib/chronic/handlers.rb +13 -11
- data/lib/chronic/pointer.rb +3 -3
- data/lib/chronic/repeater.rb +2 -2
- data/lib/chronic/repeaters/repeater_hour.rb +2 -2
- data/lib/chronic/repeaters/repeater_weekend.rb +49 -0
- data/lib/chronic.rb +26 -1
- data/lib/numerizer/numerizer.rb +103 -0
- data/test/{parse_numbers.rb → test_Numerizer.rb} +6 -8
- data/test/test_RepeaterWeekend.rb +75 -0
- data/test/test_parsing.rb +189 -146
- metadata +10 -5
data/History.txt
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
= 0.2.0 2007-03-20
|
|
2
|
+
|
|
3
|
+
* fixed time overflow issue
|
|
4
|
+
* implemented numerizer, allowing the use of number words (e.g. five weeks ago) (shalev)
|
|
5
|
+
|
|
6
|
+
= 0.1.6 2006-01-15
|
|
7
|
+
|
|
8
|
+
* added 'weekend' support (eventualbuddha)
|
|
9
|
+
|
|
1
10
|
= 0.1.5 2006-12-20
|
|
2
11
|
|
|
3
12
|
* fixed 'aug 20' returning next year if current month is august
|
data/Manifest.txt
CHANGED
|
@@ -26,10 +26,11 @@ lib/chronic/repeaters/repeater_weekend.rb
|
|
|
26
26
|
lib/chronic/repeaters/repeater_year.rb
|
|
27
27
|
lib/chronic/scalar.rb
|
|
28
28
|
lib/chronic/separator.rb
|
|
29
|
-
|
|
29
|
+
lib/numerizer/numerizer.rb
|
|
30
30
|
test/suite.rb
|
|
31
31
|
test/test_Chronic.rb
|
|
32
32
|
test/test_Handler.rb
|
|
33
|
+
test/test_Numerizer.rb
|
|
33
34
|
test/test_RepeaterDayName.rb
|
|
34
35
|
test/test_RepeaterFortnight.rb
|
|
35
36
|
test/test_RepeaterHour.rb
|
|
@@ -37,6 +38,7 @@ test/test_RepeaterMonth.rb
|
|
|
37
38
|
test/test_RepeaterMonthName.rb
|
|
38
39
|
test/test_RepeaterTime.rb
|
|
39
40
|
test/test_RepeaterWeek.rb
|
|
41
|
+
test/test_RepeaterWeekend.rb
|
|
40
42
|
test/test_RepeaterYear.rb
|
|
41
43
|
test/test_Span.rb
|
|
42
44
|
test/test_Token.rb
|
data/Rakefile
CHANGED
|
@@ -10,6 +10,8 @@ Hoe.new('chronic', Chronic::VERSION) do |p|
|
|
|
10
10
|
p.description = p.paragraphs_of('README.txt', 2).join("\n\n")
|
|
11
11
|
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
|
12
12
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
|
13
|
+
p.need_tar = false
|
|
14
|
+
p.extra_deps = []
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
# vim: syntax=Ruby
|
data/lib/chronic/chronic.rb
CHANGED
|
@@ -101,6 +101,7 @@ module Chronic
|
|
|
101
101
|
# ordinals (third => 3rd)
|
|
102
102
|
def pre_normalize(text) #:nodoc:
|
|
103
103
|
normalized_text = text.to_s.downcase
|
|
104
|
+
normalized_text = numericize_numbers(normalized_text)
|
|
104
105
|
normalized_text.gsub!(/['"\.]/, '')
|
|
105
106
|
normalized_text.gsub!(/([\/\-\,\@])/) { ' ' + $1 + ' ' }
|
|
106
107
|
normalized_text.gsub!(/\btoday\b/, 'this day')
|
|
@@ -118,15 +119,12 @@ module Chronic
|
|
|
118
119
|
normalized_text.gsub!(/\btonight\b/, 'this night')
|
|
119
120
|
normalized_text.gsub!(/(?=\w)([ap]m|oclock)\b/, ' \1')
|
|
120
121
|
normalized_text.gsub!(/\b(hence|after|from)\b/, 'future')
|
|
121
|
-
normalized_text.gsub!(/\ba\b/, '1')
|
|
122
|
-
normalized_text.gsub!(/\s+/, ' ')
|
|
123
|
-
normalized_text = numericize_numbers(normalized_text)
|
|
124
122
|
normalized_text = numericize_ordinals(normalized_text)
|
|
125
123
|
end
|
|
126
124
|
|
|
127
125
|
# Convert number words to numbers (three => 3)
|
|
128
126
|
def numericize_numbers(text) #:nodoc:
|
|
129
|
-
text
|
|
127
|
+
Numerizer.numerize(text)
|
|
130
128
|
end
|
|
131
129
|
|
|
132
130
|
# Convert ordinal words to numeric ordinals (third => 3rd)
|
data/lib/chronic/handlers.rb
CHANGED
|
@@ -214,17 +214,19 @@ module Chronic
|
|
|
214
214
|
def handle_s_r_p(tokens, options) #:nodoc:
|
|
215
215
|
repeater = tokens[1].get_tag(Repeater)
|
|
216
216
|
|
|
217
|
-
span =
|
|
218
|
-
case true
|
|
219
|
-
when [RepeaterYear, RepeaterSeason, RepeaterSeasonName, RepeaterMonth, RepeaterMonthName, RepeaterFortnight, RepeaterWeek].include?(repeater.class)
|
|
220
|
-
|
|
221
|
-
when [RepeaterWeekend, RepeaterDay, RepeaterDayName, RepeaterDayPortion, RepeaterHour].include?(repeater.class)
|
|
222
|
-
|
|
223
|
-
when [RepeaterMinute, RepeaterSecond].include?(repeater.class)
|
|
224
|
-
|
|
225
|
-
else
|
|
226
|
-
|
|
227
|
-
end
|
|
217
|
+
# span =
|
|
218
|
+
# case true
|
|
219
|
+
# when [RepeaterYear, RepeaterSeason, RepeaterSeasonName, RepeaterMonth, RepeaterMonthName, RepeaterFortnight, RepeaterWeek].include?(repeater.class)
|
|
220
|
+
# self.parse("this hour", :guess => false, :now => @now)
|
|
221
|
+
# when [RepeaterWeekend, RepeaterDay, RepeaterDayName, RepeaterDayPortion, RepeaterHour].include?(repeater.class)
|
|
222
|
+
# self.parse("this minute", :guess => false, :now => @now)
|
|
223
|
+
# when [RepeaterMinute, RepeaterSecond].include?(repeater.class)
|
|
224
|
+
# self.parse("this second", :guess => false, :now => @now)
|
|
225
|
+
# else
|
|
226
|
+
# raise(ChronicPain, "Invalid repeater: #{repeater.class}")
|
|
227
|
+
# end
|
|
228
|
+
|
|
229
|
+
span = self.parse("this second", :guess => false, :now => @now)
|
|
228
230
|
|
|
229
231
|
self.handle_srp(tokens, span, options)
|
|
230
232
|
end
|
data/lib/chronic/pointer.rb
CHANGED
|
@@ -10,9 +10,9 @@ module Chronic
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def self.scan_for_all(token)
|
|
13
|
-
scanner = {/
|
|
14
|
-
/
|
|
15
|
-
/
|
|
13
|
+
scanner = {/\bpast\b/ => :past,
|
|
14
|
+
/\bfuture\b/ => :future,
|
|
15
|
+
/\bin\b/ => :future}
|
|
16
16
|
scanner.keys.each do |scanner_item|
|
|
17
17
|
return self.new(scanner[scanner_item]) if scanner_item =~ token.word
|
|
18
18
|
end
|
data/lib/chronic/repeater.rb
CHANGED
|
@@ -72,7 +72,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
|
|
|
72
72
|
/^months?$/ => :month,
|
|
73
73
|
/^fortnights?$/ => :fortnight,
|
|
74
74
|
/^weeks?$/ => :week,
|
|
75
|
-
/^weekends?$/ => :
|
|
75
|
+
/^weekends?$/ => :weekend,
|
|
76
76
|
/^days?$/ => :day,
|
|
77
77
|
/^hours?$/ => :hour,
|
|
78
78
|
/^minutes?$/ => :minute,
|
|
@@ -104,7 +104,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
|
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
def this(pointer)
|
|
107
|
-
!@now.nil? || raise("Start point must be set before calling #
|
|
107
|
+
!@now.nil? || raise("Start point must be set before calling #this")
|
|
108
108
|
[:future, :past, :none].include?(pointer) || raise("First argument 'pointer' must be one of :past, :future, :none")
|
|
109
109
|
end
|
|
110
110
|
|
|
@@ -24,8 +24,8 @@ class Chronic::RepeaterHour < Chronic::Repeater #:nodoc:
|
|
|
24
24
|
|
|
25
25
|
case pointer
|
|
26
26
|
when :future
|
|
27
|
-
hour_start = Time.
|
|
28
|
-
hour_end = Time.
|
|
27
|
+
hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
|
|
28
|
+
hour_end = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
|
|
29
29
|
when :past
|
|
30
30
|
hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour)
|
|
31
31
|
hour_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
class Chronic::RepeaterWeekend < Chronic::Repeater #:nodoc:
|
|
2
2
|
WEEKEND_SECONDS = 172_800 # (2 * 24 * 60 * 60)
|
|
3
3
|
|
|
4
|
+
def next(pointer)
|
|
5
|
+
super
|
|
6
|
+
|
|
7
|
+
if !@current_week_start
|
|
8
|
+
case pointer
|
|
9
|
+
when :future
|
|
10
|
+
saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
|
|
11
|
+
saturday_repeater.start = @now
|
|
12
|
+
next_saturday_span = saturday_repeater.next(:future)
|
|
13
|
+
@current_week_start = next_saturday_span.begin
|
|
14
|
+
when :past
|
|
15
|
+
saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
|
|
16
|
+
saturday_repeater.start = (@now + Chronic::RepeaterDay::DAY_SECONDS)
|
|
17
|
+
last_saturday_span = saturday_repeater.next(:past)
|
|
18
|
+
@current_week_start = last_saturday_span.begin
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
direction = pointer == :future ? 1 : -1
|
|
22
|
+
@current_week_start += direction * Chronic::RepeaterWeek::WEEK_SECONDS
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Chronic::Span.new(@current_week_start, @current_week_start + WEEKEND_SECONDS)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def this(pointer = :future)
|
|
29
|
+
super
|
|
30
|
+
|
|
31
|
+
case pointer
|
|
32
|
+
when :future, :none
|
|
33
|
+
saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
|
|
34
|
+
saturday_repeater.start = @now
|
|
35
|
+
this_saturday_span = saturday_repeater.this(:future)
|
|
36
|
+
Chronic::Span.new(this_saturday_span.begin, this_saturday_span.begin + WEEKEND_SECONDS)
|
|
37
|
+
when :past
|
|
38
|
+
saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
|
|
39
|
+
saturday_repeater.start = @now
|
|
40
|
+
last_saturday_span = saturday_repeater.this(:past)
|
|
41
|
+
Chronic::Span.new(last_saturday_span.begin, last_saturday_span.begin + WEEKEND_SECONDS)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def offset(span, amount, pointer)
|
|
46
|
+
direction = pointer == :future ? 1 : -1
|
|
47
|
+
weekend = Chronic::RepeaterWeekend.new(:weekend)
|
|
48
|
+
weekend.start = span.begin
|
|
49
|
+
start = weekend.next(pointer).begin + (amount - 1) * direction * Chronic::RepeaterWeek::WEEK_SECONDS
|
|
50
|
+
Chronic::Span.new(start, start + (span.end - span.begin))
|
|
51
|
+
end
|
|
52
|
+
|
|
4
53
|
def width
|
|
5
54
|
WEEKEND_SECONDS
|
|
6
55
|
end
|
data/lib/chronic.rb
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
#
|
|
8
8
|
#=============================================================================
|
|
9
9
|
|
|
10
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
|
11
|
+
|
|
10
12
|
require 'chronic/chronic'
|
|
11
13
|
require 'chronic/handlers'
|
|
12
14
|
|
|
@@ -33,8 +35,10 @@ require 'chronic/scalar'
|
|
|
33
35
|
require 'chronic/ordinal'
|
|
34
36
|
require 'chronic/separator'
|
|
35
37
|
|
|
38
|
+
require 'numerizer/numerizer'
|
|
39
|
+
|
|
36
40
|
module Chronic
|
|
37
|
-
VERSION = "0.
|
|
41
|
+
VERSION = "0.2.0"
|
|
38
42
|
|
|
39
43
|
def self.debug; false; end
|
|
40
44
|
end
|
|
@@ -44,4 +48,25 @@ alias p_orig p
|
|
|
44
48
|
def p(val)
|
|
45
49
|
p_orig val
|
|
46
50
|
puts
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class Time
|
|
54
|
+
def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
|
|
55
|
+
if second >= 60
|
|
56
|
+
minute += second / 60
|
|
57
|
+
second = second % 60
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if minute >= 60
|
|
61
|
+
hour += minute / 60
|
|
62
|
+
minute = minute % 60
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if hour >= 24
|
|
66
|
+
day += hour / 24
|
|
67
|
+
hour = hour % 24
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
Time.local(year, month, day, hour, minute, second)
|
|
71
|
+
end
|
|
47
72
|
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
require 'strscan'
|
|
2
|
+
|
|
3
|
+
class Numerizer
|
|
4
|
+
|
|
5
|
+
DIRECT_NUMS = [
|
|
6
|
+
['eleven', '11'],
|
|
7
|
+
['twelve', '12'],
|
|
8
|
+
['thirteen', '13'],
|
|
9
|
+
['fourteen', '14'],
|
|
10
|
+
['fifteen', '15'],
|
|
11
|
+
['sixteen', '16'],
|
|
12
|
+
['seventeen', '17'],
|
|
13
|
+
['eighteen', '18'],
|
|
14
|
+
['nineteen', '19'],
|
|
15
|
+
['ninteen', '19'], # Common mis-spelling
|
|
16
|
+
['zero', '0'],
|
|
17
|
+
['one', '1'],
|
|
18
|
+
['two', '2'],
|
|
19
|
+
['three', '3'],
|
|
20
|
+
['four(\W|$)', '4\1'], # The weird regex is so that it matches four but not fourty
|
|
21
|
+
['five', '5'],
|
|
22
|
+
['six(\W|$)', '6\1'],
|
|
23
|
+
['seven(\W|$)', '7\1'],
|
|
24
|
+
['eight(\W|$)', '8\1'],
|
|
25
|
+
['nine(\W|$)', '9\1'],
|
|
26
|
+
['ten', '10'],
|
|
27
|
+
['\ba[\b^$]', '1'] # doesn't make sense for an 'a' at the end to be a 1
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
TEN_PREFIXES = [ ['twenty', 20],
|
|
31
|
+
['thirty', 30],
|
|
32
|
+
['fourty', 40],
|
|
33
|
+
['fifty', 50],
|
|
34
|
+
['sixty', 60],
|
|
35
|
+
['seventy', 70],
|
|
36
|
+
['eighty', 80],
|
|
37
|
+
['ninety', 90]
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
BIG_PREFIXES = [ ['hundred', 100],
|
|
41
|
+
['thousand', 1000],
|
|
42
|
+
['million', 1_000_000],
|
|
43
|
+
['billion', 1_000_000_000],
|
|
44
|
+
['trillion', 1_000_000_000_000],
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
class << self
|
|
48
|
+
def numerize(string)
|
|
49
|
+
string = string.dup
|
|
50
|
+
|
|
51
|
+
# preprocess
|
|
52
|
+
string.gsub!(/ +|([^\d])-([^d])/, '\1 \2') # will mutilate hyphenated-words but shouldn't matter for date extraction
|
|
53
|
+
string.gsub!(/a half/, 'haAlf') # take the 'a' out so it doesn't turn into a 1, save the half for the end
|
|
54
|
+
|
|
55
|
+
# easy/direct replacements
|
|
56
|
+
|
|
57
|
+
DIRECT_NUMS.each do |dn|
|
|
58
|
+
string.gsub!(/#{dn[0]}/i, dn[1])
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# ten, twenty, etc.
|
|
62
|
+
|
|
63
|
+
TEN_PREFIXES.each do |tp|
|
|
64
|
+
string.gsub!(/(?:#{tp[0]})( *\d(?=[^\d]|$))*/i) { (tp[1] + $1.to_i).to_s }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# hundreds, thousands, millions, etc.
|
|
68
|
+
|
|
69
|
+
BIG_PREFIXES.each do |bp|
|
|
70
|
+
string.gsub!(/(\d*) *#{bp[0]}/i) { (bp[1] * $1.to_i).to_s}
|
|
71
|
+
andition(string)
|
|
72
|
+
#combine_numbers(string) # Should to be more efficient way to do this
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# fractional addition
|
|
76
|
+
# I'm not combining this with the previous block as using float addition complicates the strings
|
|
77
|
+
# (with extraneous .0's and such )
|
|
78
|
+
string.gsub!(/(\d+)(?: | and |-)*haAlf/i) { ($1.to_f + 0.5).to_s }
|
|
79
|
+
|
|
80
|
+
string
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
def andition(string)
|
|
85
|
+
sc = StringScanner.new(string)
|
|
86
|
+
while(sc.scan_until(/(\d+)( | and )(\d+)(?=[^\w]|$)/i))
|
|
87
|
+
if sc[2] =~ /and/ || sc[1].size > sc[3].size
|
|
88
|
+
string[(sc.pos - sc.matched_size)..(sc.pos-1)] = (sc[1].to_i + sc[3].to_i).to_s
|
|
89
|
+
sc.reset
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# def combine_numbers(string)
|
|
95
|
+
# sc = StringScanner.new(string)
|
|
96
|
+
# while(sc.scan_until(/(\d+)(?: | and |-)(\d+)(?=[^\w]|$)/i))
|
|
97
|
+
# string[(sc.pos - sc.matched_size)..(sc.pos-1)] = (sc[1].to_i + sc[2].to_i).to_s
|
|
98
|
+
# sc.reset
|
|
99
|
+
# end
|
|
100
|
+
# end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
__END__
|
|
2
|
-
|
|
3
1
|
require 'test/unit'
|
|
2
|
+
require 'chronic'
|
|
4
3
|
|
|
5
4
|
class ParseNumbersTest < Test::Unit::TestCase
|
|
6
5
|
|
|
7
|
-
def
|
|
8
|
-
strings = {1 => 'one',
|
|
6
|
+
def test_straight_parsing
|
|
7
|
+
strings = { 1 => 'one',
|
|
9
8
|
5 => 'five',
|
|
10
9
|
10 => 'ten',
|
|
11
10
|
11 => 'eleven',
|
|
@@ -24,7 +23,7 @@ class ParseNumbersTest < Test::Unit::TestCase
|
|
|
24
23
|
100 => 'a hundred',
|
|
25
24
|
100 => 'one hundred',
|
|
26
25
|
150 => 'one hundred and fifty',
|
|
27
|
-
|
|
26
|
+
# 150 => 'one fifty',
|
|
28
27
|
200 => 'two-hundred',
|
|
29
28
|
500 => '5 hundred',
|
|
30
29
|
999 => 'nine hundred and ninety nine',
|
|
@@ -40,11 +39,10 @@ class ParseNumbersTest < Test::Unit::TestCase
|
|
|
40
39
|
1_000_000 => 'one million',
|
|
41
40
|
1_250_007 => 'one million two hundred fifty thousand and seven',
|
|
42
41
|
1_000_000_000 => 'one billion',
|
|
43
|
-
1_000_000_001 => 'one billion and one'}
|
|
42
|
+
1_000_000_001 => 'one billion and one' }
|
|
44
43
|
|
|
45
44
|
strings.keys.sort.each do |key|
|
|
46
|
-
assert_equal key,
|
|
45
|
+
assert_equal key, Numerizer.numerize(strings[key]).to_i
|
|
47
46
|
end
|
|
48
47
|
end
|
|
49
|
-
|
|
50
48
|
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'chronic'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
|
|
4
|
+
class TestRepeaterWeekend < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
# Wed Aug 16 14:00:00 2006
|
|
8
|
+
@now = Time.local(2006, 8, 16, 14, 0, 0, 0)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_next_future
|
|
12
|
+
weekend = Chronic::RepeaterWeekend.new(:weekend)
|
|
13
|
+
weekend.start = @now
|
|
14
|
+
|
|
15
|
+
next_weekend = weekend.next(:future)
|
|
16
|
+
assert_equal Time.local(2006, 8, 19), next_weekend.begin
|
|
17
|
+
assert_equal Time.local(2006, 8, 21), next_weekend.end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_next_past
|
|
21
|
+
weekend = Chronic::RepeaterWeekend.new(:weekend)
|
|
22
|
+
weekend.start = @now
|
|
23
|
+
|
|
24
|
+
next_weekend = weekend.next(:past)
|
|
25
|
+
assert_equal Time.local(2006, 8, 12), next_weekend.begin
|
|
26
|
+
assert_equal Time.local(2006, 8, 14), next_weekend.end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_this_future
|
|
30
|
+
weekend = Chronic::RepeaterWeekend.new(:weekend)
|
|
31
|
+
weekend.start = @now
|
|
32
|
+
|
|
33
|
+
next_weekend = weekend.this(:future)
|
|
34
|
+
assert_equal Time.local(2006, 8, 19), next_weekend.begin
|
|
35
|
+
assert_equal Time.local(2006, 8, 21), next_weekend.end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_this_past
|
|
39
|
+
weekend = Chronic::RepeaterWeekend.new(:weekend)
|
|
40
|
+
weekend.start = @now
|
|
41
|
+
|
|
42
|
+
next_weekend = weekend.this(:past)
|
|
43
|
+
assert_equal Time.local(2006, 8, 12), next_weekend.begin
|
|
44
|
+
assert_equal Time.local(2006, 8, 14), next_weekend.end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_this_none
|
|
48
|
+
weekend = Chronic::RepeaterWeekend.new(:weekend)
|
|
49
|
+
weekend.start = @now
|
|
50
|
+
|
|
51
|
+
next_weekend = weekend.this(:future)
|
|
52
|
+
assert_equal Time.local(2006, 8, 19), next_weekend.begin
|
|
53
|
+
assert_equal Time.local(2006, 8, 21), next_weekend.end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_offset
|
|
57
|
+
span = Chronic::Span.new(@now, @now + 1)
|
|
58
|
+
|
|
59
|
+
offset_span = Chronic::RepeaterWeekend.new(:weekend).offset(span, 3, :future)
|
|
60
|
+
|
|
61
|
+
assert_equal Time.local(2006, 9, 2), offset_span.begin
|
|
62
|
+
assert_equal Time.local(2006, 9, 2, 0, 0, 1), offset_span.end
|
|
63
|
+
|
|
64
|
+
offset_span = Chronic::RepeaterWeekend.new(:weekend).offset(span, 1, :past)
|
|
65
|
+
|
|
66
|
+
assert_equal Time.local(2006, 8, 12), offset_span.begin
|
|
67
|
+
assert_equal Time.local(2006, 8, 12, 0, 0, 1), offset_span.end
|
|
68
|
+
|
|
69
|
+
offset_span = Chronic::RepeaterWeekend.new(:weekend).offset(span, 0, :future)
|
|
70
|
+
|
|
71
|
+
assert_equal Time.local(2006, 8, 12), offset_span.begin
|
|
72
|
+
assert_equal Time.local(2006, 8, 12, 0, 0, 1), offset_span.end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
data/test/test_parsing.rb
CHANGED
|
@@ -2,496 +2,535 @@ require 'chronic'
|
|
|
2
2
|
require 'test/unit'
|
|
3
3
|
|
|
4
4
|
class TestParsing < Test::Unit::TestCase
|
|
5
|
+
# Wed Aug 16 14:00:00 UTC 2006
|
|
6
|
+
TIME_2006_08_16_14_00_00 = Time.local(2006, 8, 16, 14, 0, 0, 0)
|
|
5
7
|
|
|
6
8
|
def setup
|
|
7
|
-
|
|
8
|
-
@time_2006_08_16_14_00_00 = Time.local(2006, 8, 16, 14, 0, 0, 0)
|
|
9
|
-
@time_2006_08_16_03_00_00 = Time.local(2006, 8, 16, 3, 0, 0, 0)
|
|
9
|
+
@time_2006_08_16_14_00_00 = TIME_2006_08_16_14_00_00
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def
|
|
12
|
+
def test_parse_guess_dates
|
|
13
13
|
# rm_sd
|
|
14
14
|
|
|
15
|
-
time =
|
|
15
|
+
time = parse_now("may 27")
|
|
16
16
|
assert_equal Time.local(2007, 5, 27, 12), time
|
|
17
17
|
|
|
18
|
-
time =
|
|
18
|
+
time = parse_now("may 28", :context => :past)
|
|
19
19
|
assert_equal Time.local(2006, 5, 28, 12), time
|
|
20
20
|
|
|
21
|
-
time =
|
|
21
|
+
time = parse_now("may 28 5pm", :context => :past)
|
|
22
22
|
assert_equal Time.local(2006, 5, 28, 17), time
|
|
23
23
|
|
|
24
|
-
time =
|
|
24
|
+
time = parse_now("may 28 at 5pm", :context => :past)
|
|
25
25
|
assert_equal Time.local(2006, 5, 28, 17), time
|
|
26
26
|
|
|
27
|
-
time =
|
|
27
|
+
time = parse_now("may 28 at 5:32.19pm", :context => :past)
|
|
28
28
|
assert_equal Time.local(2006, 5, 28, 17, 32, 19), time
|
|
29
29
|
|
|
30
30
|
# rm_od
|
|
31
31
|
|
|
32
|
-
time =
|
|
32
|
+
time = parse_now("may 27th")
|
|
33
33
|
assert_equal Time.local(2007, 5, 27, 12), time
|
|
34
34
|
|
|
35
|
-
time =
|
|
35
|
+
time = parse_now("may 27th", :context => :past)
|
|
36
36
|
assert_equal Time.local(2006, 5, 27, 12), time
|
|
37
37
|
|
|
38
|
-
time =
|
|
38
|
+
time = parse_now("may 27th 5:00 pm", :context => :past)
|
|
39
39
|
assert_equal Time.local(2006, 5, 27, 17), time
|
|
40
40
|
|
|
41
|
-
time =
|
|
41
|
+
time = parse_now("may 27th at 5pm", :context => :past)
|
|
42
42
|
assert_equal Time.local(2006, 5, 27, 17), time
|
|
43
43
|
|
|
44
|
-
time =
|
|
44
|
+
time = parse_now("may 27th at 5", :ambiguous_time_range => :none)
|
|
45
45
|
assert_equal Time.local(2007, 5, 27, 5), time
|
|
46
46
|
|
|
47
47
|
# rm_sy
|
|
48
48
|
|
|
49
|
-
time =
|
|
49
|
+
time = parse_now("June 1979")
|
|
50
50
|
assert_equal Time.local(1979, 6, 16, 0), time
|
|
51
51
|
|
|
52
|
-
time =
|
|
52
|
+
time = parse_now("dec 79")
|
|
53
53
|
assert_equal Time.local(1979, 12, 16, 12), time
|
|
54
54
|
|
|
55
55
|
# rm_sd_sy
|
|
56
56
|
|
|
57
|
-
time =
|
|
57
|
+
time = parse_now("jan 3 2010")
|
|
58
58
|
assert_equal Time.local(2010, 1, 3, 12), time
|
|
59
59
|
|
|
60
|
-
time =
|
|
60
|
+
time = parse_now("jan 3 2010 midnight")
|
|
61
61
|
assert_equal Time.local(2010, 1, 4, 0), time
|
|
62
62
|
|
|
63
|
-
time =
|
|
63
|
+
time = parse_now("jan 3 2010 at midnight")
|
|
64
64
|
assert_equal Time.local(2010, 1, 4, 0), time
|
|
65
65
|
|
|
66
|
-
time =
|
|
66
|
+
time = parse_now("jan 3 2010 at 4", :ambiguous_time_range => :none)
|
|
67
67
|
assert_equal Time.local(2010, 1, 3, 4), time
|
|
68
68
|
|
|
69
|
-
#time =
|
|
69
|
+
#time = parse_now("January 12, '00")
|
|
70
70
|
#assert_equal Time.local(2000, 1, 12, 12), time
|
|
71
71
|
|
|
72
|
-
time =
|
|
72
|
+
time = parse_now("may 27 79")
|
|
73
73
|
assert_equal Time.local(1979, 5, 27, 12), time
|
|
74
74
|
|
|
75
|
-
time =
|
|
75
|
+
time = parse_now("may 27 79 4:30")
|
|
76
76
|
assert_equal Time.local(1979, 5, 27, 16, 30), time
|
|
77
77
|
|
|
78
|
-
time =
|
|
78
|
+
time = parse_now("may 27 79 at 4:30", :ambiguous_time_range => :none)
|
|
79
79
|
assert_equal Time.local(1979, 5, 27, 4, 30), time
|
|
80
80
|
|
|
81
81
|
# sd_rm_sy
|
|
82
82
|
|
|
83
|
-
time =
|
|
83
|
+
time = parse_now("3 jan 2010")
|
|
84
84
|
assert_equal Time.local(2010, 1, 3, 12), time
|
|
85
85
|
|
|
86
|
-
time =
|
|
86
|
+
time = parse_now("3 jan 2010 4pm")
|
|
87
87
|
assert_equal Time.local(2010, 1, 3, 16), time
|
|
88
88
|
|
|
89
89
|
# sm_sd_sy
|
|
90
90
|
|
|
91
|
-
time =
|
|
91
|
+
time = parse_now("5/27/1979")
|
|
92
92
|
assert_equal Time.local(1979, 5, 27, 12), time
|
|
93
93
|
|
|
94
|
-
time =
|
|
94
|
+
time = parse_now("5/27/1979 4am")
|
|
95
95
|
assert_equal Time.local(1979, 5, 27, 4), time
|
|
96
96
|
|
|
97
97
|
# sd_sm_sy
|
|
98
98
|
|
|
99
|
-
time =
|
|
99
|
+
time = parse_now("27/5/1979")
|
|
100
100
|
assert_equal Time.local(1979, 5, 27, 12), time
|
|
101
101
|
|
|
102
|
-
time =
|
|
102
|
+
time = parse_now("27/5/1979 @ 0700")
|
|
103
103
|
assert_equal Time.local(1979, 5, 27, 7), time
|
|
104
104
|
|
|
105
105
|
# sm_sy
|
|
106
106
|
|
|
107
|
-
time =
|
|
107
|
+
time = parse_now("05/06")
|
|
108
108
|
assert_equal Time.local(2006, 5, 16, 12), time
|
|
109
109
|
|
|
110
|
-
time =
|
|
110
|
+
time = parse_now("12/06")
|
|
111
111
|
assert_equal Time.local(2006, 12, 16, 12), time
|
|
112
112
|
|
|
113
|
-
time =
|
|
113
|
+
time = parse_now("13/06")
|
|
114
114
|
assert_equal nil, time
|
|
115
115
|
|
|
116
116
|
# sy_sm_sd
|
|
117
117
|
|
|
118
|
-
time =
|
|
118
|
+
time = parse_now("2000-1-1")
|
|
119
119
|
assert_equal Time.local(2000, 1, 1, 12), time
|
|
120
120
|
|
|
121
|
-
time =
|
|
121
|
+
time = parse_now("2006-08-20")
|
|
122
122
|
assert_equal Time.local(2006, 8, 20, 12), time
|
|
123
123
|
|
|
124
|
-
time =
|
|
124
|
+
time = parse_now("2006-08-20 7pm")
|
|
125
125
|
assert_equal Time.local(2006, 8, 20, 19), time
|
|
126
126
|
|
|
127
|
-
time =
|
|
127
|
+
time = parse_now("2006-08-20 03:00")
|
|
128
128
|
assert_equal Time.local(2006, 8, 20, 3), time
|
|
129
129
|
|
|
130
|
-
time =
|
|
130
|
+
time = parse_now("2006-08-20 03:30:30")
|
|
131
131
|
assert_equal Time.local(2006, 8, 20, 3, 30, 30), time
|
|
132
132
|
|
|
133
|
-
time =
|
|
133
|
+
time = parse_now("2006-08-20 15:30:30")
|
|
134
134
|
assert_equal Time.local(2006, 8, 20, 15, 30, 30), time
|
|
135
135
|
|
|
136
|
-
time =
|
|
136
|
+
time = parse_now("2006-08-20 15:30.30")
|
|
137
137
|
assert_equal Time.local(2006, 8, 20, 15, 30, 30), time
|
|
138
138
|
|
|
139
139
|
# rm_sd_rt
|
|
140
140
|
|
|
141
|
-
#time =
|
|
141
|
+
#time = parse_now("jan 5 13:00")
|
|
142
142
|
#assert_equal Time.local(2007, 1, 5, 13), time
|
|
143
143
|
|
|
144
144
|
# due to limitations of the Time class, these don't work
|
|
145
145
|
|
|
146
|
-
time =
|
|
146
|
+
time = parse_now("may 40")
|
|
147
147
|
assert_equal nil, time
|
|
148
148
|
|
|
149
|
-
time =
|
|
149
|
+
time = parse_now("may 27 40")
|
|
150
150
|
assert_equal nil, time
|
|
151
151
|
|
|
152
|
-
time =
|
|
152
|
+
time = parse_now("1800-08-20")
|
|
153
153
|
assert_equal nil, time
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
def test_parse_guess_r
|
|
157
|
-
time =
|
|
157
|
+
time = parse_now("friday")
|
|
158
158
|
assert_equal Time.local(2006, 8, 18, 12), time
|
|
159
159
|
|
|
160
|
-
time =
|
|
160
|
+
time = parse_now("5")
|
|
161
161
|
assert_equal Time.local(2006, 8, 16, 17), time
|
|
162
162
|
|
|
163
|
-
time = Chronic.parse("5", :now =>
|
|
163
|
+
time = Chronic.parse("5", :now => Time.local(2006, 8, 16, 3, 0, 0, 0), :ambiguous_time_range => :none)
|
|
164
164
|
assert_equal Time.local(2006, 8, 16, 5), time
|
|
165
165
|
|
|
166
|
-
time =
|
|
166
|
+
time = parse_now("13:00")
|
|
167
167
|
assert_equal Time.local(2006, 8, 17, 13), time
|
|
168
168
|
|
|
169
|
-
time =
|
|
169
|
+
time = parse_now("13:45")
|
|
170
170
|
assert_equal Time.local(2006, 8, 17, 13, 45), time
|
|
171
171
|
|
|
172
|
-
time =
|
|
172
|
+
time = parse_now("november")
|
|
173
173
|
assert_equal Time.local(2006, 11, 16), time
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
def test_parse_guess_rr
|
|
177
|
-
time =
|
|
177
|
+
time = parse_now("friday 13:00")
|
|
178
178
|
assert_equal Time.local(2006, 8, 18, 13), time
|
|
179
179
|
|
|
180
|
-
time =
|
|
180
|
+
time = parse_now("monday 4:00")
|
|
181
181
|
assert_equal Time.local(2006, 8, 21, 16), time
|
|
182
182
|
|
|
183
|
-
time =
|
|
183
|
+
time = parse_now("sat 4:00", :ambiguous_time_range => :none)
|
|
184
184
|
assert_equal Time.local(2006, 8, 19, 4), time
|
|
185
185
|
|
|
186
|
-
time =
|
|
186
|
+
time = parse_now("sunday 4:20", :ambiguous_time_range => :none)
|
|
187
187
|
assert_equal Time.local(2006, 8, 20, 4, 20), time
|
|
188
188
|
|
|
189
|
-
time =
|
|
189
|
+
time = parse_now("4 pm")
|
|
190
190
|
assert_equal Time.local(2006, 8, 16, 16), time
|
|
191
191
|
|
|
192
|
-
time =
|
|
192
|
+
time = parse_now("4 am", :ambiguous_time_range => :none)
|
|
193
193
|
assert_equal Time.local(2006, 8, 16, 4), time
|
|
194
194
|
|
|
195
|
-
time =
|
|
195
|
+
time = parse_now("4:00 in the morning")
|
|
196
196
|
assert_equal Time.local(2006, 8, 16, 4), time
|
|
197
197
|
|
|
198
|
-
time =
|
|
198
|
+
time = parse_now("november 4")
|
|
199
199
|
assert_equal Time.local(2006, 11, 4, 12), time
|
|
200
200
|
|
|
201
|
-
time =
|
|
201
|
+
time = parse_now("aug 24")
|
|
202
202
|
assert_equal Time.local(2006, 8, 24, 12), time
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
def test_parse_guess_rrr
|
|
206
|
-
time =
|
|
206
|
+
time = parse_now("friday 1 pm")
|
|
207
207
|
assert_equal Time.local(2006, 8, 18, 13), time
|
|
208
208
|
|
|
209
|
-
time =
|
|
209
|
+
time = parse_now("friday 11 at night")
|
|
210
210
|
assert_equal Time.local(2006, 8, 18, 23), time
|
|
211
211
|
|
|
212
|
-
time =
|
|
212
|
+
time = parse_now("friday 11 in the evening")
|
|
213
213
|
assert_equal Time.local(2006, 8, 18, 23), time
|
|
214
214
|
|
|
215
|
-
time =
|
|
215
|
+
time = parse_now("sunday 6am")
|
|
216
216
|
assert_equal Time.local(2006, 8, 20, 6), time
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
def test_parse_guess_gr
|
|
220
220
|
# year
|
|
221
221
|
|
|
222
|
-
time =
|
|
222
|
+
time = parse_now("this year")
|
|
223
223
|
assert_equal Time.local(2006, 10, 24, 12, 30), time
|
|
224
224
|
|
|
225
|
-
time =
|
|
225
|
+
time = parse_now("this year", :context => :past)
|
|
226
226
|
assert_equal Time.local(2006, 4, 24, 12, 30), time
|
|
227
227
|
|
|
228
228
|
# month
|
|
229
229
|
|
|
230
|
-
time =
|
|
230
|
+
time = parse_now("this month")
|
|
231
231
|
assert_equal Time.local(2006, 8, 24, 12), time
|
|
232
232
|
|
|
233
|
-
time =
|
|
233
|
+
time = parse_now("this month", :context => :past)
|
|
234
234
|
assert_equal Time.local(2006, 8, 8, 12), time
|
|
235
235
|
|
|
236
236
|
# month name
|
|
237
237
|
|
|
238
|
-
time =
|
|
238
|
+
time = parse_now("last november")
|
|
239
239
|
assert_equal Time.local(2005, 11, 16), time
|
|
240
240
|
|
|
241
241
|
# fortnight
|
|
242
242
|
|
|
243
|
-
time =
|
|
243
|
+
time = parse_now("this fortnight")
|
|
244
244
|
assert_equal Time.local(2006, 8, 21, 19, 30), time
|
|
245
245
|
|
|
246
|
-
time =
|
|
246
|
+
time = parse_now("this fortnight", :context => :past)
|
|
247
247
|
assert_equal Time.local(2006, 8, 14, 19), time
|
|
248
248
|
|
|
249
249
|
# week
|
|
250
250
|
|
|
251
|
-
time =
|
|
251
|
+
time = parse_now("this week")
|
|
252
252
|
assert_equal Time.local(2006, 8, 18, 7, 30), time
|
|
253
253
|
|
|
254
|
-
time =
|
|
254
|
+
time = parse_now("this week", :context => :past)
|
|
255
255
|
assert_equal Time.local(2006, 8, 14, 19), time
|
|
256
256
|
|
|
257
|
+
# weekend
|
|
258
|
+
|
|
259
|
+
time = parse_now("this weekend")
|
|
260
|
+
assert_equal Time.local(2006, 8, 20), time
|
|
261
|
+
|
|
262
|
+
time = parse_now("this weekend", :context => :past)
|
|
263
|
+
assert_equal Time.local(2006, 8, 13), time
|
|
264
|
+
|
|
265
|
+
time = parse_now("last weekend")
|
|
266
|
+
assert_equal Time.local(2006, 8, 13), time
|
|
267
|
+
|
|
257
268
|
# day
|
|
258
269
|
|
|
259
|
-
time =
|
|
270
|
+
time = parse_now("this day")
|
|
260
271
|
assert_equal Time.local(2006, 8, 16, 19, 30), time
|
|
261
272
|
|
|
262
|
-
time =
|
|
273
|
+
time = parse_now("this day", :context => :past)
|
|
263
274
|
assert_equal Time.local(2006, 8, 16, 7), time
|
|
264
275
|
|
|
265
|
-
time =
|
|
276
|
+
time = parse_now("today")
|
|
266
277
|
assert_equal Time.local(2006, 8, 16, 19, 30), time
|
|
267
278
|
|
|
268
|
-
time =
|
|
279
|
+
time = parse_now("yesterday")
|
|
269
280
|
assert_equal Time.local(2006, 8, 15, 12), time
|
|
270
281
|
|
|
271
|
-
time =
|
|
282
|
+
time = parse_now("tomorrow")
|
|
272
283
|
assert_equal Time.local(2006, 8, 17, 12), time
|
|
273
284
|
|
|
274
285
|
# day name
|
|
275
286
|
|
|
276
|
-
time =
|
|
287
|
+
time = parse_now("this tuesday")
|
|
277
288
|
assert_equal Time.local(2006, 8, 22, 12), time
|
|
278
289
|
|
|
279
|
-
time =
|
|
290
|
+
time = parse_now("next tuesday")
|
|
280
291
|
assert_equal Time.local(2006, 8, 22, 12), time
|
|
281
292
|
|
|
282
|
-
time =
|
|
293
|
+
time = parse_now("last tuesday")
|
|
283
294
|
assert_equal Time.local(2006, 8, 15, 12), time
|
|
284
295
|
|
|
285
|
-
time =
|
|
296
|
+
time = parse_now("this wed")
|
|
286
297
|
assert_equal Time.local(2006, 8, 23, 12), time
|
|
287
298
|
|
|
288
|
-
time =
|
|
299
|
+
time = parse_now("next wed")
|
|
289
300
|
assert_equal Time.local(2006, 8, 23, 12), time
|
|
290
301
|
|
|
291
|
-
time =
|
|
302
|
+
time = parse_now("last wed")
|
|
292
303
|
assert_equal Time.local(2006, 8, 9, 12), time
|
|
293
304
|
|
|
294
305
|
# day portion
|
|
295
306
|
|
|
296
|
-
time =
|
|
307
|
+
time = parse_now("this morning")
|
|
297
308
|
assert_equal Time.local(2006, 8, 16, 9), time
|
|
298
309
|
|
|
299
|
-
time =
|
|
310
|
+
time = parse_now("tonight")
|
|
300
311
|
assert_equal Time.local(2006, 8, 16, 22), time
|
|
301
312
|
|
|
302
313
|
# second
|
|
303
314
|
|
|
304
|
-
time =
|
|
315
|
+
time = parse_now("this second")
|
|
305
316
|
assert_equal Time.local(2006, 8, 16, 14), time
|
|
306
317
|
|
|
307
|
-
time =
|
|
318
|
+
time = parse_now("this second", :context => :past)
|
|
308
319
|
assert_equal Time.local(2006, 8, 16, 14), time
|
|
309
320
|
|
|
310
|
-
time =
|
|
321
|
+
time = parse_now("next second")
|
|
311
322
|
assert_equal Time.local(2006, 8, 16, 14, 0, 1), time
|
|
312
323
|
|
|
313
|
-
time =
|
|
324
|
+
time = parse_now("last second")
|
|
314
325
|
assert_equal Time.local(2006, 8, 16, 13, 59, 59), time
|
|
315
326
|
end
|
|
316
327
|
|
|
317
328
|
def test_parse_guess_grr
|
|
318
|
-
time =
|
|
329
|
+
time = parse_now("yesterday at 4:00")
|
|
319
330
|
assert_equal Time.local(2006, 8, 15, 16), time
|
|
320
331
|
|
|
321
|
-
time =
|
|
332
|
+
time = parse_now("today at 9:00")
|
|
322
333
|
assert_equal Time.local(2006, 8, 16, 9), time
|
|
323
334
|
|
|
324
|
-
time =
|
|
335
|
+
time = parse_now("today at 2100")
|
|
325
336
|
assert_equal Time.local(2006, 8, 16, 21), time
|
|
326
337
|
|
|
327
|
-
time =
|
|
338
|
+
time = parse_now("this day at 0900")
|
|
328
339
|
assert_equal Time.local(2006, 8, 16, 9), time
|
|
329
340
|
|
|
330
|
-
time =
|
|
341
|
+
time = parse_now("tomorrow at 0900")
|
|
331
342
|
assert_equal Time.local(2006, 8, 17, 9), time
|
|
332
343
|
|
|
333
|
-
time =
|
|
344
|
+
time = parse_now("yesterday at 4:00", :ambiguous_time_range => :none)
|
|
334
345
|
assert_equal Time.local(2006, 8, 15, 4), time
|
|
335
346
|
|
|
336
|
-
time =
|
|
347
|
+
time = parse_now("last friday at 4:00")
|
|
337
348
|
assert_equal Time.local(2006, 8, 11, 16), time
|
|
338
349
|
|
|
339
|
-
time =
|
|
350
|
+
time = parse_now("next wed 4:00")
|
|
340
351
|
assert_equal Time.local(2006, 8, 23, 16), time
|
|
341
352
|
|
|
342
|
-
time =
|
|
353
|
+
time = parse_now("yesterday afternoon")
|
|
343
354
|
assert_equal Time.local(2006, 8, 15, 15), time
|
|
344
355
|
|
|
345
|
-
time =
|
|
356
|
+
time = parse_now("last week tuesday")
|
|
346
357
|
assert_equal Time.local(2006, 8, 8, 12), time
|
|
347
358
|
end
|
|
348
359
|
|
|
349
360
|
def test_parse_guess_grrr
|
|
350
|
-
time =
|
|
361
|
+
time = parse_now("today at 6:00pm")
|
|
351
362
|
assert_equal Time.local(2006, 8, 16, 18), time
|
|
352
363
|
|
|
353
|
-
time =
|
|
364
|
+
time = parse_now("today at 6:00am")
|
|
354
365
|
assert_equal Time.local(2006, 8, 16, 6), time
|
|
355
366
|
|
|
356
|
-
time =
|
|
367
|
+
time = parse_now("this day 1800")
|
|
357
368
|
assert_equal Time.local(2006, 8, 16, 18), time
|
|
358
369
|
|
|
359
|
-
time =
|
|
370
|
+
time = parse_now("yesterday at 4:00pm")
|
|
360
371
|
assert_equal Time.local(2006, 8, 15, 16), time
|
|
361
372
|
end
|
|
362
373
|
|
|
363
374
|
def test_parse_guess_rgr
|
|
364
|
-
time =
|
|
375
|
+
time = parse_now("afternoon yesterday")
|
|
365
376
|
assert_equal Time.local(2006, 8, 15, 15), time
|
|
366
377
|
|
|
367
|
-
time =
|
|
378
|
+
time = parse_now("tuesday last week")
|
|
368
379
|
assert_equal Time.local(2006, 8, 8, 12), time
|
|
369
380
|
end
|
|
370
381
|
|
|
371
382
|
def test_parse_guess_s_r_p
|
|
372
383
|
# past
|
|
373
384
|
|
|
374
|
-
time =
|
|
375
|
-
assert_equal Time.local(2003, 8, 16, 14
|
|
385
|
+
time = parse_now("3 years ago")
|
|
386
|
+
assert_equal Time.local(2003, 8, 16, 14), time
|
|
376
387
|
|
|
377
|
-
time =
|
|
378
|
-
assert_equal Time.local(2006, 7, 16, 14
|
|
388
|
+
time = parse_now("1 month ago")
|
|
389
|
+
assert_equal Time.local(2006, 7, 16, 14), time
|
|
379
390
|
|
|
380
|
-
time =
|
|
381
|
-
assert_equal Time.local(2006, 8, 2, 14
|
|
391
|
+
time = parse_now("1 fortnight ago")
|
|
392
|
+
assert_equal Time.local(2006, 8, 2, 14), time
|
|
382
393
|
|
|
383
|
-
time =
|
|
384
|
-
assert_equal Time.local(2006, 7, 19, 14
|
|
394
|
+
time = parse_now("2 fortnights ago")
|
|
395
|
+
assert_equal Time.local(2006, 7, 19, 14), time
|
|
385
396
|
|
|
386
|
-
time =
|
|
387
|
-
assert_equal Time.local(2006, 7, 26, 14
|
|
397
|
+
time = parse_now("3 weeks ago")
|
|
398
|
+
assert_equal Time.local(2006, 7, 26, 14), time
|
|
388
399
|
|
|
389
|
-
time =
|
|
400
|
+
time = parse_now("2 weekends ago")
|
|
401
|
+
assert_equal Time.local(2006, 8, 5), time
|
|
402
|
+
|
|
403
|
+
time = parse_now("3 days ago")
|
|
390
404
|
assert_equal Time.local(2006, 8, 13, 14), time
|
|
391
405
|
|
|
392
|
-
#time =
|
|
406
|
+
#time = parse_now("1 monday ago")
|
|
393
407
|
#assert_equal Time.local(2006, 8, 14, 12), time
|
|
394
408
|
|
|
395
|
-
time =
|
|
409
|
+
time = parse_now("5 mornings ago")
|
|
396
410
|
assert_equal Time.local(2006, 8, 12, 9), time
|
|
397
411
|
|
|
398
|
-
time =
|
|
412
|
+
time = parse_now("7 hours ago")
|
|
399
413
|
assert_equal Time.local(2006, 8, 16, 7), time
|
|
400
414
|
|
|
401
|
-
time =
|
|
415
|
+
time = parse_now("3 minutes ago")
|
|
402
416
|
assert_equal Time.local(2006, 8, 16, 13, 57), time
|
|
403
417
|
|
|
404
|
-
time =
|
|
418
|
+
time = parse_now("20 seconds before now")
|
|
405
419
|
assert_equal Time.local(2006, 8, 16, 13, 59, 40), time
|
|
406
420
|
|
|
407
421
|
# future
|
|
408
422
|
|
|
409
|
-
time =
|
|
423
|
+
time = parse_now("3 years from now")
|
|
410
424
|
assert_equal Time.local(2009, 8, 16, 14, 0, 0), time
|
|
411
425
|
|
|
412
|
-
time =
|
|
413
|
-
assert_equal Time.local(2007, 2, 16, 14
|
|
426
|
+
time = parse_now("6 months hence")
|
|
427
|
+
assert_equal Time.local(2007, 2, 16, 14), time
|
|
414
428
|
|
|
415
|
-
time =
|
|
416
|
-
assert_equal Time.local(2006, 9, 27, 14
|
|
429
|
+
time = parse_now("3 fortnights hence")
|
|
430
|
+
assert_equal Time.local(2006, 9, 27, 14), time
|
|
417
431
|
|
|
418
|
-
time =
|
|
432
|
+
time = parse_now("1 week from now")
|
|
419
433
|
assert_equal Time.local(2006, 8, 23, 14, 0, 0), time
|
|
420
434
|
|
|
421
|
-
time =
|
|
435
|
+
time = parse_now("1 weekend from now")
|
|
436
|
+
assert_equal Time.local(2006, 8, 19), time
|
|
437
|
+
|
|
438
|
+
time = parse_now("2 weekends from now")
|
|
439
|
+
assert_equal Time.local(2006, 8, 26), time
|
|
440
|
+
|
|
441
|
+
time = parse_now("1 day hence")
|
|
422
442
|
assert_equal Time.local(2006, 8, 17, 14), time
|
|
423
443
|
|
|
424
|
-
time =
|
|
444
|
+
time = parse_now("5 mornings hence")
|
|
425
445
|
assert_equal Time.local(2006, 8, 21, 9), time
|
|
426
446
|
|
|
427
|
-
time =
|
|
447
|
+
time = parse_now("1 hour from now")
|
|
428
448
|
assert_equal Time.local(2006, 8, 16, 15), time
|
|
429
449
|
|
|
430
|
-
time =
|
|
450
|
+
time = parse_now("20 minutes hence")
|
|
431
451
|
assert_equal Time.local(2006, 8, 16, 14, 20), time
|
|
432
452
|
|
|
433
|
-
time =
|
|
453
|
+
time = parse_now("20 seconds from now")
|
|
434
454
|
assert_equal Time.local(2006, 8, 16, 14, 0, 20), time
|
|
455
|
+
|
|
456
|
+
time = Chronic.parse("2 months ago", :now => Time.parse("2007-03-07 23:30"))
|
|
457
|
+
assert_equal Time.local(2007, 1, 7, 23, 30), time
|
|
435
458
|
end
|
|
436
459
|
|
|
437
460
|
def test_parse_guess_p_s_r
|
|
438
|
-
time =
|
|
461
|
+
time = parse_now("in 3 hours")
|
|
439
462
|
assert_equal Time.local(2006, 8, 16, 17), time
|
|
440
463
|
end
|
|
441
464
|
|
|
442
465
|
def test_parse_guess_s_r_p_a
|
|
443
466
|
# past
|
|
444
467
|
|
|
445
|
-
time =
|
|
468
|
+
time = parse_now("3 years ago tomorrow")
|
|
446
469
|
assert_equal Time.local(2003, 8, 17, 12), time
|
|
447
470
|
|
|
448
|
-
time =
|
|
471
|
+
time = parse_now("3 years ago this friday")
|
|
449
472
|
assert_equal Time.local(2003, 8, 18, 12), time
|
|
450
473
|
|
|
451
|
-
time =
|
|
474
|
+
time = parse_now("3 months ago saturday at 5:00 pm")
|
|
452
475
|
assert_equal Time.local(2006, 5, 19, 17), time
|
|
453
476
|
|
|
454
|
-
time =
|
|
477
|
+
time = parse_now("2 days from this second")
|
|
455
478
|
assert_equal Time.local(2006, 8, 18, 14), time
|
|
456
479
|
|
|
457
|
-
time =
|
|
480
|
+
time = parse_now("7 hours before tomorrow at midnight")
|
|
458
481
|
assert_equal Time.local(2006, 8, 17, 17), time
|
|
459
482
|
|
|
460
483
|
# future
|
|
461
484
|
end
|
|
462
485
|
|
|
463
486
|
def test_parse_guess_o_r_s_r
|
|
464
|
-
time =
|
|
487
|
+
time = parse_now("3rd wednesday in november")
|
|
465
488
|
assert_equal Time.local(2006, 11, 15, 12), time
|
|
466
489
|
|
|
467
|
-
time =
|
|
490
|
+
time = parse_now("10th wednesday in november")
|
|
468
491
|
assert_equal nil, time
|
|
469
492
|
end
|
|
470
493
|
|
|
471
494
|
def test_parse_guess_o_r_g_r
|
|
472
|
-
time =
|
|
495
|
+
time = parse_now("3rd month next year")
|
|
473
496
|
assert_equal Time.local(2007, 3, 16, 12, 30), time
|
|
474
497
|
|
|
475
|
-
time =
|
|
498
|
+
time = parse_now("3rd thursday this september")
|
|
476
499
|
assert_equal Time.local(2006, 9, 21, 12), time
|
|
477
500
|
|
|
478
|
-
time =
|
|
501
|
+
time = parse_now("4th day last week")
|
|
479
502
|
assert_equal Time.local(2006, 8, 9, 12), time
|
|
480
503
|
end
|
|
481
504
|
|
|
482
505
|
def test_parse_guess_nonsense
|
|
483
|
-
time =
|
|
506
|
+
time = parse_now("some stupid nonsense")
|
|
484
507
|
assert_equal nil, time
|
|
485
508
|
end
|
|
486
509
|
|
|
487
510
|
def test_parse_span
|
|
488
|
-
span =
|
|
511
|
+
span = parse_now("friday", :guess => false)
|
|
489
512
|
assert_equal Time.local(2006, 8, 18), span.begin
|
|
490
513
|
assert_equal Time.local(2006, 8, 19), span.end
|
|
491
514
|
|
|
492
|
-
span =
|
|
515
|
+
span = parse_now("november", :guess => false)
|
|
493
516
|
assert_equal Time.local(2006, 11), span.begin
|
|
494
517
|
assert_equal Time.local(2006, 12), span.end
|
|
518
|
+
|
|
519
|
+
span = Chronic.parse("weekend" , :now => @time_2006_08_16_14_00_00, :guess => false)
|
|
520
|
+
assert_equal Time.local(2006, 8, 19), span.begin
|
|
521
|
+
assert_equal Time.local(2006, 8, 21), span.end
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
def test_parse_words
|
|
525
|
+
assert_equal parse_now("33 days from now"), parse_now("thirty-three days from now")
|
|
526
|
+
assert_equal parse_now("2867532 seconds from now"), parse_now("two million eight hundred and sixty seven thousand five hundred and thirty two seconds from now")
|
|
527
|
+
assert_equal parse_now("may 10th"), parse_now("may tenth")
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
def test_parse_only_complete_pointers
|
|
531
|
+
assert_equal parse_now("eat pasty buns today at 2pm"), @time_2006_08_16_14_00_00
|
|
532
|
+
assert_equal parse_now("futuristically speaking today at 2pm"), @time_2006_08_16_14_00_00
|
|
533
|
+
assert_equal parse_now("meeting today at 2pm"), @time_2006_08_16_14_00_00
|
|
495
534
|
end
|
|
496
535
|
|
|
497
536
|
def test_argument_validation
|
|
@@ -504,4 +543,8 @@ class TestParsing < Test::Unit::TestCase
|
|
|
504
543
|
end
|
|
505
544
|
end
|
|
506
545
|
|
|
546
|
+
private
|
|
547
|
+
def parse_now(string, options={})
|
|
548
|
+
Chronic.parse(string, {:now => TIME_2006_08_16_14_00_00 }.merge(options))
|
|
549
|
+
end
|
|
507
550
|
end
|
metadata
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
|
-
rubygems_version: 0.
|
|
2
|
+
rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
|
4
4
|
name: chronic
|
|
5
5
|
version: !ruby/object:Gem::Version
|
|
6
|
-
version: 0.
|
|
7
|
-
date:
|
|
6
|
+
version: 0.2.0
|
|
7
|
+
date: 2007-03-20 00:00:00 -07:00
|
|
8
8
|
summary: A natural language date parser
|
|
9
9
|
require_paths:
|
|
10
10
|
- lib
|
|
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
|
25
25
|
platform: ruby
|
|
26
26
|
signing_key:
|
|
27
27
|
cert_chain:
|
|
28
|
+
post_install_message:
|
|
28
29
|
authors:
|
|
29
30
|
- Ryan Davis
|
|
30
31
|
files:
|
|
@@ -56,10 +57,11 @@ files:
|
|
|
56
57
|
- lib/chronic/repeaters/repeater_year.rb
|
|
57
58
|
- lib/chronic/scalar.rb
|
|
58
59
|
- lib/chronic/separator.rb
|
|
59
|
-
-
|
|
60
|
+
- lib/numerizer/numerizer.rb
|
|
60
61
|
- test/suite.rb
|
|
61
62
|
- test/test_Chronic.rb
|
|
62
63
|
- test/test_Handler.rb
|
|
64
|
+
- test/test_Numerizer.rb
|
|
63
65
|
- test/test_RepeaterDayName.rb
|
|
64
66
|
- test/test_RepeaterFortnight.rb
|
|
65
67
|
- test/test_RepeaterHour.rb
|
|
@@ -67,6 +69,7 @@ files:
|
|
|
67
69
|
- test/test_RepeaterMonthName.rb
|
|
68
70
|
- test/test_RepeaterTime.rb
|
|
69
71
|
- test/test_RepeaterWeek.rb
|
|
72
|
+
- test/test_RepeaterWeekend.rb
|
|
70
73
|
- test/test_RepeaterYear.rb
|
|
71
74
|
- test/test_Span.rb
|
|
72
75
|
- test/test_Token.rb
|
|
@@ -74,6 +77,7 @@ files:
|
|
|
74
77
|
test_files:
|
|
75
78
|
- test/test_Chronic.rb
|
|
76
79
|
- test/test_Handler.rb
|
|
80
|
+
- test/test_Numerizer.rb
|
|
77
81
|
- test/test_parsing.rb
|
|
78
82
|
- test/test_RepeaterDayName.rb
|
|
79
83
|
- test/test_RepeaterFortnight.rb
|
|
@@ -82,6 +86,7 @@ test_files:
|
|
|
82
86
|
- test/test_RepeaterMonthName.rb
|
|
83
87
|
- test/test_RepeaterTime.rb
|
|
84
88
|
- test/test_RepeaterWeek.rb
|
|
89
|
+
- test/test_RepeaterWeekend.rb
|
|
85
90
|
- test/test_RepeaterYear.rb
|
|
86
91
|
- test/test_Span.rb
|
|
87
92
|
- test/test_Token.rb
|
|
@@ -103,5 +108,5 @@ dependencies:
|
|
|
103
108
|
requirements:
|
|
104
109
|
- - ">="
|
|
105
110
|
- !ruby/object:Gem::Version
|
|
106
|
-
version: 1.
|
|
111
|
+
version: 1.2.0
|
|
107
112
|
version:
|