chronic 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -12,6 +12,7 @@ Chronic can be installed via RubyGems:
12
12
 
13
13
  You can parse strings containing a natural language date using the Chronic.parse method.
14
14
 
15
+ require 'rubygems'
15
16
  require 'chronic'
16
17
 
17
18
  Time.now #=> Sun Aug 27 23:18:25 PDT 2006
data/lib/chronic.rb CHANGED
@@ -34,8 +34,9 @@ require 'chronic/ordinal'
34
34
  require 'chronic/separator'
35
35
 
36
36
  module Chronic
37
+ @version = "0.1.3"
37
38
  def self.debug=(val); @debug = val; end
38
39
  end
39
40
 
40
- Chronic.debug = false
41
+ Chronic.debug = true
41
42
 
@@ -50,7 +50,7 @@ module Chronic
50
50
  specified_options.keys.each do |key|
51
51
  default_options.keys.include?(key) || raise(InvalidArgumentException, "#{key} is not a valid option key.")
52
52
  end
53
- [:past, :future].include?(options[:context]) || raise(InvalidArgumentException, "Invalid value '#{options[:context]}' for :context specified. Valid values are :past and :future.")
53
+ [:past, :future, :none].include?(options[:context]) || raise(InvalidArgumentException, "Invalid value ':#{options[:context]}' for :context specified. Valid values are :past and :future.")
54
54
 
55
55
  # store now for later =)
56
56
  @now = options[:now]
@@ -73,7 +73,7 @@ module Chronic
73
73
  # strip any non-tagged tokens
74
74
  @tokens = @tokens.select { |token| token.tagged? }
75
75
 
76
- if @debug
76
+ if true
77
77
  puts "+---------------------------------------------------"
78
78
  puts "| " + @tokens.to_s
79
79
  puts "+---------------------------------------------------"
@@ -35,6 +35,7 @@ module Chronic
35
35
  self.definitions[:date].each do |handler|
36
36
  if handler.match(tokens, self.definitions)
37
37
  good_tokens = tokens.select { |o| !o.get_tag Separator }
38
+ puts "--#{handler}"
38
39
  return self.send(handler.handler_method, good_tokens, options)
39
40
  end
40
41
  end
@@ -67,6 +68,7 @@ module Chronic
67
68
  end
68
69
 
69
70
  # I guess you're out of luck!
71
+ puts "--SUCKY"
70
72
  return nil
71
73
  end
72
74
 
@@ -282,14 +284,25 @@ module Chronic
282
284
 
283
285
  head = repeaters.shift
284
286
  head.start = @now
285
-
287
+
286
288
  case grabber.type
287
- when :last: outer_span = head.next(:past)
288
- when :this: outer_span = head.this(options[:context])
289
- when :next: outer_span = head.next(:future)
289
+ when :last
290
+ outer_span = head.next(:past)
291
+ when :this
292
+ puts "--THIS"
293
+ puts "--#{repeaters}"
294
+ if repeaters.size > 0
295
+ puts "--NONE"
296
+ outer_span = head.this(:none)
297
+ else
298
+ outer_span = head.this(options[:context])
299
+ end
300
+ when :next
301
+ outer_span = head.next(:future)
290
302
  else raise(ChronicPain, "Invalid grabber")
291
303
  end
292
304
 
305
+ puts "--#{outer_span}"
293
306
  anchor = find_within(repeaters, outer_span, pointer)
294
307
  end
295
308
 
@@ -307,11 +320,12 @@ module Chronic
307
320
  # Returns a Span representing the innermost time span
308
321
  # or nil if no repeater union could be found
309
322
  def find_within(tags, span, pointer) #:nodoc:
323
+ puts "--#{span}"
310
324
  return span if tags.empty?
311
325
 
312
326
  head, *rest = tags
313
327
  head.start = pointer == :future ? span.begin : span.end
314
- h = head.this(pointer)
328
+ h = head.this(:none)
315
329
 
316
330
  if span.include?(h.begin) || span.include?(h.end)
317
331
  return find_within(rest, h, pointer)
@@ -6,7 +6,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
6
6
  if t = self.scan_for_day_names(tokens[i]) then tokens[i].tag(t); next end
7
7
  if t = self.scan_for_day_portions(tokens[i]) then tokens[i].tag(t); next end
8
8
  if t = self.scan_for_times(tokens[i], options) then tokens[i].tag(t); next end
9
- if t = self.scan_for_units(tokens[i]) then tokens[i].tag(t); next end
9
+ if t = self.scan_for_units(tokens[i]) then tokens[i].tag(t); next end
10
10
  end
11
11
  tokens
12
12
  end
@@ -20,7 +20,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
20
20
  /^jun\.?e?$/ => :june,
21
21
  /^jul\.?y?$/ => :july,
22
22
  /^aug\.?(ust)?$/ => :august,
23
- /^sep\.?(tember)?$/ => :september,
23
+ /^sep\.?(t\.?|tember)?$/ => :september,
24
24
  /^oct\.?(ober)?$/ => :october,
25
25
  /^nov\.?(ember)?$/ => :november,
26
26
  /^dec\.?(ember)?$/ => :december}
@@ -52,7 +52,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
52
52
  /^mornings?$/ => :morning,
53
53
  /^afternoons?$/ => :afternoon,
54
54
  /^evenings?$/ => :evening,
55
- /^nights?$/ => :night}
55
+ /^(night|nite)s?$/ => :night}
56
56
  scanner.keys.each do |scanner_item|
57
57
  return Chronic::RepeaterDayPortion.new(scanner[scanner_item]) if scanner_item =~ token.word
58
58
  end
@@ -105,7 +105,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
105
105
 
106
106
  def this(pointer)
107
107
  !@now.nil? || raise("Start point must be set before calling #next")
108
- [:future, :past].include?(pointer) || raise("First argument 'pointer' must be one of :past or :future")
108
+ [:future, :past, :none].include?(pointer) || raise("First argument 'pointer' must be one of :past, :future, :none")
109
109
  end
110
110
 
111
111
  def to_s
@@ -24,6 +24,9 @@ class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
24
24
  when :past
25
25
  day_begin = Time.local(@now.year, @now.month, @now.day)
26
26
  day_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
27
+ when :none
28
+ day_begin = Time.local(@now.year, @now.month, @now.day)
29
+ day_end = Time.local(@now.year, @now.month, @now.day) + DAY_SECONDS
27
30
  end
28
31
 
29
32
  Chronic::Span.new(day_begin, day_end)
@@ -25,6 +25,7 @@ class Chronic::RepeaterDayName < Chronic::Repeater #:nodoc:
25
25
  def this(pointer = :future)
26
26
  super
27
27
 
28
+ pointer = :future if pointer == :none
28
29
  self.next(pointer)
29
30
  end
30
31
 
@@ -29,6 +29,8 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
29
29
  def this(pointer = :future)
30
30
  super
31
31
 
32
+ pointer = :future if pointer == :none
33
+
32
34
  case pointer
33
35
  when :future
34
36
  this_fortnight_start = Time.local(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
@@ -42,7 +44,6 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
42
44
  this_fortnight_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
43
45
  sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
44
46
  sunday_repeater.start = @now
45
- #sunday_repeater.next(:past)
46
47
  last_sunday_span = sunday_repeater.next(:past)
47
48
  this_fortnight_start = last_sunday_span.begin
48
49
  Chronic::Span.new(this_fortnight_start, this_fortnight_end)
@@ -1,9 +1,30 @@
1
1
  class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
2
2
  MINUTE_SECONDS = 60
3
3
 
4
+ def next(pointer = :future)
5
+ super
6
+
7
+ direction = pointer == :future ? 1 : -1
8
+
9
+ raise 'not implemented'
10
+ end
11
+
4
12
  def this(pointer = :future)
5
- minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
6
- Chronic::Span.new(minute_begin, minute_begin + MINUTE_SECONDS)
13
+ super
14
+
15
+ case pointer
16
+ when :future
17
+ minute_begin = @now
18
+ minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
19
+ when :past
20
+ minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
21
+ minute_end = @now
22
+ when :none
23
+ minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
24
+ minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
25
+ end
26
+
27
+ Chronic::Span.new(minute_begin, minute_end)
7
28
  end
8
29
 
9
30
  def offset(span, amount, pointer)
@@ -24,6 +24,9 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
24
24
  when :past
25
25
  month_start = Time.local(@now.year, @now.month)
26
26
  month_end = Time.local(@now.year, @now.month, @now.day)
27
+ when :none
28
+ month_start = Time.local(@now.year, @now.month)
29
+ month_end = self.offset_by(Time.local(@now.year, @now.month), 1, :future)
27
30
  end
28
31
 
29
32
  Chronic::Span.new(month_start, month_end)
@@ -47,6 +47,8 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
47
47
  def this(pointer = :future)
48
48
  super
49
49
 
50
+ pointer = :future if pointer == :none
51
+
50
52
  self.next(pointer)
51
53
  end
52
54
 
@@ -16,6 +16,8 @@ class Chronic::RepeaterSecond < Chronic::Repeater #:nodoc:
16
16
  end
17
17
 
18
18
  def this(pointer = :future)
19
+ super
20
+
19
21
  Chronic::Span.new(@now, @now + 1)
20
22
  end
21
23
 
@@ -92,7 +92,10 @@ class Chronic::RepeaterTime < Chronic::Repeater #:nodoc:
92
92
  end
93
93
 
94
94
  def this(context = :future)
95
- [:future, :past].include?(context) || raise("First argument 'context' must be one of :past or :future")
95
+ super
96
+
97
+ context = :future if context == :none
98
+
96
99
  self.next(context)
97
100
  end
98
101
 
@@ -44,6 +44,12 @@ class Chronic::RepeaterWeek < Chronic::Repeater #:nodoc:
44
44
  last_sunday_span = sunday_repeater.next(:past)
45
45
  this_week_start = last_sunday_span.begin
46
46
  Chronic::Span.new(this_week_start, this_week_end)
47
+ when :none
48
+ sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
49
+ sunday_repeater.start = @now
50
+ last_sunday_span = sunday_repeater.next(:past)
51
+ this_week_start = last_sunday_span.begin
52
+ Chronic::Span.new(this_week_start, this_week_start + WEEK_SECONDS)
47
53
  end
48
54
  end
49
55
 
@@ -28,6 +28,9 @@ class Chronic::RepeaterYear < Chronic::Repeater #:nodoc:
28
28
  when :past
29
29
  this_year_start = Time.local(@now.year, 1, 1)
30
30
  this_year_end = Time.local(@now.year, @now.month, @now.day)
31
+ when :none
32
+ this_year_start = Time.local(@now.year, 1, 1)
33
+ this_year_end = Time.local(@now.year + 1, 1, 1)
31
34
  end
32
35
 
33
36
  Chronic::Span.new(this_year_start, this_year_end)
@@ -40,7 +40,7 @@ module Chronic
40
40
  end
41
41
 
42
42
  def self.scan_for_years(token, post_token)
43
- if token.word =~ /^\d\d(\d\d)?$/
43
+ if token.word =~ /^([1-9]\d)?\d\d?$/
44
44
  unless post_token && %w{am pm morning afternoon evening night}.include?(post_token)
45
45
  return ScalarYear.new(token.word.to_i)
46
46
  end
data/test/test_parsing.rb CHANGED
@@ -300,10 +300,22 @@ class TestParsing < Test::Unit::TestCase
300
300
  assert_equal Time.local(2006, 8, 16, 13, 59, 59), time
301
301
  end
302
302
 
303
- def test_parse_guess_grr
303
+ def test_parse_guess_grr
304
304
  time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00)
305
305
  assert_equal Time.local(2006, 8, 15, 16), time
306
306
 
307
+ time = Chronic.parse("today at 9:00", :now => @time_2006_08_16_14_00_00)
308
+ assert_equal Time.local(2006, 8, 16, 9), time
309
+
310
+ time = Chronic.parse("today at 2100", :now => @time_2006_08_16_14_00_00)
311
+ assert_equal Time.local(2006, 8, 16, 21), time
312
+
313
+ time = Chronic.parse("this day at 0900", :now => @time_2006_08_16_14_00_00)
314
+ assert_equal Time.local(2006, 8, 16, 9), time
315
+
316
+ time = Chronic.parse("tomorrow at 0900", :now => @time_2006_08_16_14_00_00)
317
+ assert_equal Time.local(2006, 8, 17, 9), time
318
+
307
319
  time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
308
320
  assert_equal Time.local(2006, 8, 15, 4), time
309
321
 
@@ -324,6 +336,9 @@ class TestParsing < Test::Unit::TestCase
324
336
  time = Chronic.parse("today at 6:00pm", :now => @time_2006_08_16_14_00_00)
325
337
  assert_equal Time.local(2006, 8, 16, 18), time
326
338
 
339
+ time = Chronic.parse("today at 6:00am", :now => @time_2006_08_16_14_00_00)
340
+ assert_equal Time.local(2006, 8, 16, 6), time
341
+
327
342
  time = Chronic.parse("this day 1800", :now => @time_2006_08_16_14_00_00)
328
343
  assert_equal Time.local(2006, 8, 16, 18), time
329
344
 
@@ -358,7 +373,7 @@ class TestParsing < Test::Unit::TestCase
358
373
  assert_equal Time.local(2006, 7, 26, 14, 30, 30), time
359
374
 
360
375
  time = Chronic.parse("3 days ago", :now => @time_2006_08_16_14_00_00)
361
- assert_equal Time.local(2006, 8, 13, 14, 0, 30), time
376
+ assert_equal Time.local(2006, 8, 13, 14), time
362
377
 
363
378
  #time = Chronic.parse("1 monday ago", :now => @time_2006_08_16_14_00_00)
364
379
  #assert_equal Time.local(2006, 8, 14, 12), time
@@ -367,7 +382,7 @@ class TestParsing < Test::Unit::TestCase
367
382
  assert_equal Time.local(2006, 8, 12, 9), time
368
383
 
369
384
  time = Chronic.parse("7 hours ago", :now => @time_2006_08_16_14_00_00)
370
- assert_equal Time.local(2006, 8, 16, 7, 0, 30), time
385
+ assert_equal Time.local(2006, 8, 16, 7), time
371
386
 
372
387
  time = Chronic.parse("3 minutes ago", :now => @time_2006_08_16_14_00_00)
373
388
  assert_equal Time.local(2006, 8, 16, 13, 57), time
@@ -390,13 +405,13 @@ class TestParsing < Test::Unit::TestCase
390
405
  assert_equal Time.local(2006, 8, 23, 14, 30, 30), time
391
406
 
392
407
  time = Chronic.parse("1 day hence", :now => @time_2006_08_16_14_00_00)
393
- assert_equal Time.local(2006, 8, 17, 14, 0, 30), time
408
+ assert_equal Time.local(2006, 8, 17, 14), time
394
409
 
395
410
  time = Chronic.parse("5 mornings hence", :now => @time_2006_08_16_14_00_00)
396
411
  assert_equal Time.local(2006, 8, 21, 9), time
397
412
 
398
413
  time = Chronic.parse("1 hour from now", :now => @time_2006_08_16_14_00_00)
399
- assert_equal Time.local(2006, 8, 16, 15, 0, 30), time
414
+ assert_equal Time.local(2006, 8, 16, 15), time
400
415
 
401
416
  time = Chronic.parse("20 minutes hence", :now => @time_2006_08_16_14_00_00)
402
417
  assert_equal Time.local(2006, 8, 16, 14, 20), time
@@ -407,7 +422,7 @@ class TestParsing < Test::Unit::TestCase
407
422
 
408
423
  def test_parse_guess_p_s_r
409
424
  time = Chronic.parse("in 3 hours", :now => @time_2006_08_16_14_00_00)
410
- assert_equal Time.local(2006, 8, 16, 17, 0, 30), time
425
+ assert_equal Time.local(2006, 8, 16, 17), time
411
426
  end
412
427
 
413
428
  def test_parse_guess_s_r_p_a
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: chronic
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.2
7
- date: 2006-09-16 00:00:00 -07:00
6
+ version: 0.1.3
7
+ date: 2006-10-20 00:00:00 -07:00
8
8
  summary: A natural language date parser
9
9
  require_paths:
10
10
  - lib