chronic 0.3.0 → 0.4.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.
Files changed (43) hide show
  1. data/HISTORY.md +27 -0
  2. data/Manifest.txt +16 -5
  3. data/README.md +14 -8
  4. data/Rakefile +2 -8
  5. data/chronic.gemspec +8 -11
  6. data/lib/chronic.rb +21 -14
  7. data/lib/chronic/chronic.rb +38 -130
  8. data/lib/chronic/grabber.rb +11 -15
  9. data/lib/chronic/handlers.rb +63 -40
  10. data/lib/chronic/mini_date.rb +27 -0
  11. data/lib/chronic/numerizer.rb +120 -0
  12. data/lib/chronic/ordinal.rb +5 -10
  13. data/lib/chronic/pointer.rb +8 -10
  14. data/lib/chronic/repeater.rb +106 -109
  15. data/lib/chronic/repeaters/repeater_day.rb +43 -41
  16. data/lib/chronic/repeaters/repeater_day_name.rb +38 -36
  17. data/lib/chronic/repeaters/repeater_day_portion.rb +74 -73
  18. data/lib/chronic/repeaters/repeater_fortnight.rb +57 -55
  19. data/lib/chronic/repeaters/repeater_hour.rb +46 -44
  20. data/lib/chronic/repeaters/repeater_minute.rb +46 -44
  21. data/lib/chronic/repeaters/repeater_month.rb +52 -50
  22. data/lib/chronic/repeaters/repeater_month_name.rb +84 -80
  23. data/lib/chronic/repeaters/repeater_season.rb +97 -119
  24. data/lib/chronic/repeaters/repeater_season_name.rb +39 -39
  25. data/lib/chronic/repeaters/repeater_second.rb +32 -30
  26. data/lib/chronic/repeaters/repeater_time.rb +106 -101
  27. data/lib/chronic/repeaters/repeater_week.rb +60 -58
  28. data/lib/chronic/repeaters/repeater_weekday.rb +67 -58
  29. data/lib/chronic/repeaters/repeater_weekend.rb +54 -52
  30. data/lib/chronic/repeaters/repeater_year.rb +50 -48
  31. data/lib/chronic/scalar.rb +24 -16
  32. data/lib/chronic/separator.rb +15 -33
  33. data/lib/chronic/span.rb +31 -0
  34. data/lib/chronic/tag.rb +26 -0
  35. data/lib/chronic/time_zone.rb +7 -9
  36. data/lib/chronic/token.rb +35 -0
  37. data/test/helper.rb +5 -6
  38. data/test/test_Chronic.rb +5 -0
  39. data/test/test_Numerizer.rb +60 -39
  40. data/test/test_RepeaterHour.rb +4 -0
  41. data/test/test_parsing.rb +104 -13
  42. metadata +14 -20
  43. data/lib/chronic/numerizer/numerizer.rb +0 -97
@@ -1,52 +1,54 @@
1
- class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
2
- DAY_SECONDS = 86_400 # (24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterDay < Repeater #:nodoc:
3
+ DAY_SECONDS = 86_400 # (24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_day_start = nil
7
- end
8
-
9
- def next(pointer)
10
- super
11
-
12
- if !@current_day_start
13
- @current_day_start = Chronic.time_class.local(@now.year, @now.month, @now.day)
5
+ def initialize(type)
6
+ super
7
+ @current_day_start = nil
14
8
  end
15
9
 
16
- direction = pointer == :future ? 1 : -1
17
- @current_day_start += direction * DAY_SECONDS
10
+ def next(pointer)
11
+ super
18
12
 
19
- Chronic::Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
20
- end
13
+ if !@current_day_start
14
+ @current_day_start = Chronic.time_class.local(@now.year, @now.month, @now.day)
15
+ end
16
+
17
+ direction = pointer == :future ? 1 : -1
18
+ @current_day_start += direction * DAY_SECONDS
21
19
 
22
- def this(pointer = :future)
23
- super
24
-
25
- case pointer
26
- when :future
27
- day_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
28
- day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
29
- when :past
30
- day_begin = Time.construct(@now.year, @now.month, @now.day)
31
- day_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
32
- when :none
33
- day_begin = Time.construct(@now.year, @now.month, @now.day)
34
- day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
20
+ Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
35
21
  end
36
22
 
37
- Chronic::Span.new(day_begin, day_end)
38
- end
23
+ def this(pointer = :future)
24
+ super
25
+
26
+ case pointer
27
+ when :future
28
+ day_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour)
29
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
30
+ when :past
31
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
32
+ day_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
33
+ when :none
34
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
35
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
36
+ end
37
+
38
+ Span.new(day_begin, day_end)
39
+ end
39
40
 
40
- def offset(span, amount, pointer)
41
- direction = pointer == :future ? 1 : -1
42
- span + direction * amount * DAY_SECONDS
43
- end
41
+ def offset(span, amount, pointer)
42
+ direction = pointer == :future ? 1 : -1
43
+ span + direction * amount * DAY_SECONDS
44
+ end
44
45
 
45
- def width
46
- DAY_SECONDS
47
- end
46
+ def width
47
+ DAY_SECONDS
48
+ end
48
49
 
49
- def to_s
50
- super << '-day'
50
+ def to_s
51
+ super << '-day'
52
+ end
51
53
  end
52
- end
54
+ end
@@ -1,51 +1,53 @@
1
- class Chronic::RepeaterDayName < Chronic::Repeater #:nodoc:
2
- DAY_SECONDS = 86400 # (24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterDayName < Repeater #:nodoc:
3
+ DAY_SECONDS = 86400 # (24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_day_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @current_day_start = nil
8
+ end
8
9
 
9
- def next(pointer)
10
- super
10
+ def next(pointer)
11
+ super
11
12
 
12
- direction = pointer == :future ? 1 : -1
13
+ direction = pointer == :future ? 1 : -1
13
14
 
14
- if !@current_day_start
15
- @current_day_start = Time.construct(@now.year, @now.month, @now.day)
16
- @current_day_start += direction * DAY_SECONDS
15
+ if !@current_date
16
+ @current_date = Date.new(@now.year, @now.month, @now.day)
17
+ @current_date += direction
17
18
 
18
- day_num = symbol_to_number(@type)
19
+ day_num = symbol_to_number(@type)
19
20
 
20
- while @current_day_start.wday != day_num
21
- @current_day_start += direction * DAY_SECONDS
21
+ while @current_date.wday != day_num
22
+ @current_date += direction
23
+ end
24
+ else
25
+ @current_date += direction * 7
22
26
  end
23
- else
24
- @current_day_start += direction * 7 * DAY_SECONDS
27
+ next_date = @current_date.succ
28
+ Span.new(Time.construct(@current_date.year, @current_date.month, @current_date.day), Time.construct(next_date.year, next_date.month, next_date.day))
25
29
  end
26
30
 
27
- Chronic::Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
28
- end
29
-
30
- def this(pointer = :future)
31
- super
31
+ def this(pointer = :future)
32
+ super
32
33
 
33
- pointer = :future if pointer == :none
34
- self.next(pointer)
35
- end
34
+ pointer = :future if pointer == :none
35
+ self.next(pointer)
36
+ end
36
37
 
37
- def width
38
- DAY_SECONDS
39
- end
38
+ def width
39
+ DAY_SECONDS
40
+ end
40
41
 
41
- def to_s
42
- super << '-dayname-' << @type.to_s
43
- end
42
+ def to_s
43
+ super << '-dayname-' << @type.to_s
44
+ end
44
45
 
45
- private
46
+ private
46
47
 
47
- def symbol_to_number(sym)
48
- lookup = {:sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3, :thursday => 4, :friday => 5, :saturday => 6}
49
- lookup[sym] || raise("Invalid symbol specified")
48
+ def symbol_to_number(sym)
49
+ lookup = {:sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3, :thursday => 4, :friday => 5, :saturday => 6}
50
+ lookup[sym] || raise("Invalid symbol specified")
51
+ end
50
52
  end
51
- end
53
+ end
@@ -1,94 +1,95 @@
1
- class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
2
- @@morning = (6 * 60 * 60)..(12 * 60 * 60) # 6am-12am
3
- @@afternoon = (13 * 60 * 60)..(17 * 60 * 60) # 1pm-5pm
4
- @@evening = (17 * 60 * 60)..(20 * 60 * 60) # 5pm-8pm
5
- @@night = (20 * 60 * 60)..(24 * 60 * 60) # 8pm-12pm
1
+ module Chronic
2
+ class RepeaterDayPortion < Repeater #:nodoc:
3
+ PORTIONS = {
4
+ :am => 0..(12 * 60 * 60 - 1),
5
+ :pm => (12 * 60 * 60)..(24 * 60 * 60 - 1),
6
+ :morning => (6 * 60 * 60)..(12 * 60 * 60), # 6am-12am,
7
+ :afternoon =>(13 * 60 * 60)..(17 * 60 * 60), # 1pm-5pm,
8
+ :evening => (17 * 60 * 60)..(20 * 60 * 60), # 5pm-8pm,
9
+ :night =>(20 * 60 * 60)..(24 * 60 * 60), # 8pm-12pm
10
+ }
6
11
 
7
- def initialize(type)
8
- super
9
- @current_span = nil
12
+ def initialize(type)
13
+ super
14
+ @current_span = nil
10
15
 
11
- if type.kind_of? Integer
12
- @range = (@type * 60 * 60)..((@type + 12) * 60 * 60)
13
- else
14
- lookup = {:am => 0..(12 * 60 * 60 - 1),
15
- :pm => (12 * 60 * 60)..(24 * 60 * 60 - 1),
16
- :morning => @@morning,
17
- :afternoon => @@afternoon,
18
- :evening => @@evening,
19
- :night => @@night}
20
- @range = lookup[type]
21
- lookup[type] || raise("Invalid type '#{type}' for RepeaterDayPortion")
16
+ if type.kind_of? Integer
17
+ @range = (@type * 60 * 60)..((@type + 12) * 60 * 60)
18
+ else
19
+ @range = PORTIONS[type]
20
+ @range || raise("Invalid type '#{type}' for RepeaterDayPortion")
21
+ end
22
+
23
+ @range || raise("Range should have been set by now")
22
24
  end
23
- @range || raise("Range should have been set by now")
24
- end
25
25
 
26
- def next(pointer)
27
- super
26
+ def next(pointer)
27
+ super
28
28
 
29
- full_day = 60 * 60 * 24
29
+ full_day = 60 * 60 * 24
30
30
 
31
- if !@current_span
32
- now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
33
- if now_seconds < @range.begin
34
- case pointer
35
- when :future
36
- range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
37
- when :past
38
- range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
39
- end
40
- elsif now_seconds > @range.end
41
- case pointer
42
- when :future
43
- range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
44
- when :past
45
- range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
31
+ if !@current_span
32
+ now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
33
+ if now_seconds < @range.begin
34
+ case pointer
35
+ when :future
36
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
37
+ when :past
38
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
39
+ end
40
+ elsif now_seconds > @range.end
41
+ case pointer
42
+ when :future
43
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
44
+ when :past
45
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
46
+ end
47
+ else
48
+ case pointer
49
+ when :future
50
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
51
+ when :past
52
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
53
+ end
46
54
  end
55
+
56
+ @current_span = Span.new(range_start, range_start + (@range.end - @range.begin))
47
57
  else
48
58
  case pointer
49
59
  when :future
50
- range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
60
+ @current_span += full_day
51
61
  when :past
52
- range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
62
+ @current_span -= full_day
53
63
  end
54
64
  end
55
-
56
- @current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
57
- else
58
- case pointer
59
- when :future
60
- @current_span += full_day
61
- when :past
62
- @current_span -= full_day
63
- end
64
65
  end
65
- end
66
66
 
67
- def this(context = :future)
68
- super
67
+ def this(context = :future)
68
+ super
69
69
 
70
- range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
71
- @current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
72
- end
70
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
71
+ @current_span = Span.new(range_start, range_start + (@range.end - @range.begin))
72
+ end
73
73
 
74
- def offset(span, amount, pointer)
75
- @now = span.begin
76
- portion_span = self.next(pointer)
77
- direction = pointer == :future ? 1 : -1
78
- portion_span + (direction * (amount - 1) * Chronic::RepeaterDay::DAY_SECONDS)
79
- end
74
+ def offset(span, amount, pointer)
75
+ @now = span.begin
76
+ portion_span = self.next(pointer)
77
+ direction = pointer == :future ? 1 : -1
78
+ portion_span + (direction * (amount - 1) * RepeaterDay::DAY_SECONDS)
79
+ end
80
80
 
81
- def width
82
- @range || raise("Range has not been set")
83
- return @current_span.width if @current_span
84
- if @type.kind_of? Integer
85
- return (12 * 60 * 60)
86
- else
87
- @range.end - @range.begin
81
+ def width
82
+ @range || raise("Range has not been set")
83
+ return @current_span.width if @current_span
84
+ if @type.kind_of? Integer
85
+ return (12 * 60 * 60)
86
+ else
87
+ @range.end - @range.begin
88
+ end
88
89
  end
89
- end
90
90
 
91
- def to_s
92
- super << '-dayportion-' << @type.to_s
91
+ def to_s
92
+ super << '-dayportion-' << @type.to_s
93
+ end
93
94
  end
94
- end
95
+ end
@@ -1,70 +1,72 @@
1
- class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
2
- FORTNIGHT_SECONDS = 1_209_600 # (14 * 24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterFortnight < Repeater #:nodoc:
3
+ FORTNIGHT_SECONDS = 1_209_600 # (14 * 24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_fortnight_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @current_fortnight_start = nil
8
+ end
9
+
10
+ def next(pointer)
11
+ super
8
12
 
9
- def next(pointer)
10
- super
13
+ if !@current_fortnight_start
14
+ case pointer
15
+ when :future
16
+ sunday_repeater = RepeaterDayName.new(:sunday)
17
+ sunday_repeater.start = @now
18
+ next_sunday_span = sunday_repeater.next(:future)
19
+ @current_fortnight_start = next_sunday_span.begin
20
+ when :past
21
+ sunday_repeater = RepeaterDayName.new(:sunday)
22
+ sunday_repeater.start = (@now + RepeaterDay::DAY_SECONDS)
23
+ 2.times { sunday_repeater.next(:past) }
24
+ last_sunday_span = sunday_repeater.next(:past)
25
+ @current_fortnight_start = last_sunday_span.begin
26
+ end
27
+ else
28
+ direction = pointer == :future ? 1 : -1
29
+ @current_fortnight_start += direction * FORTNIGHT_SECONDS
30
+ end
31
+
32
+ Span.new(@current_fortnight_start, @current_fortnight_start + FORTNIGHT_SECONDS)
33
+ end
34
+
35
+ def this(pointer = :future)
36
+ super
37
+
38
+ pointer = :future if pointer == :none
11
39
 
12
- if !@current_fortnight_start
13
40
  case pointer
14
41
  when :future
15
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
42
+ this_fortnight_start = Time.construct(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS
43
+ sunday_repeater = RepeaterDayName.new(:sunday)
16
44
  sunday_repeater.start = @now
17
- next_sunday_span = sunday_repeater.next(:future)
18
- @current_fortnight_start = next_sunday_span.begin
45
+ sunday_repeater.this(:future)
46
+ this_sunday_span = sunday_repeater.this(:future)
47
+ this_fortnight_end = this_sunday_span.begin
48
+ Span.new(this_fortnight_start, this_fortnight_end)
19
49
  when :past
20
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
21
- sunday_repeater.start = (@now + Chronic::RepeaterDay::DAY_SECONDS)
22
- 2.times { sunday_repeater.next(:past) }
50
+ this_fortnight_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
51
+ sunday_repeater = RepeaterDayName.new(:sunday)
52
+ sunday_repeater.start = @now
23
53
  last_sunday_span = sunday_repeater.next(:past)
24
- @current_fortnight_start = last_sunday_span.begin
54
+ this_fortnight_start = last_sunday_span.begin
55
+ Span.new(this_fortnight_start, this_fortnight_end)
25
56
  end
26
- else
27
- direction = pointer == :future ? 1 : -1
28
- @current_fortnight_start += direction * FORTNIGHT_SECONDS
29
57
  end
30
58
 
31
- Chronic::Span.new(@current_fortnight_start, @current_fortnight_start + FORTNIGHT_SECONDS)
32
- end
33
-
34
- def this(pointer = :future)
35
- super
36
-
37
- pointer = :future if pointer == :none
38
-
39
- case pointer
40
- when :future
41
- this_fortnight_start = Time.construct(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
42
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
43
- sunday_repeater.start = @now
44
- sunday_repeater.this(:future)
45
- this_sunday_span = sunday_repeater.this(:future)
46
- this_fortnight_end = this_sunday_span.begin
47
- Chronic::Span.new(this_fortnight_start, this_fortnight_end)
48
- when :past
49
- this_fortnight_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
50
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
51
- sunday_repeater.start = @now
52
- last_sunday_span = sunday_repeater.next(:past)
53
- this_fortnight_start = last_sunday_span.begin
54
- Chronic::Span.new(this_fortnight_start, this_fortnight_end)
59
+ def offset(span, amount, pointer)
60
+ direction = pointer == :future ? 1 : -1
61
+ span + direction * amount * FORTNIGHT_SECONDS
55
62
  end
56
- end
57
63
 
58
- def offset(span, amount, pointer)
59
- direction = pointer == :future ? 1 : -1
60
- span + direction * amount * FORTNIGHT_SECONDS
61
- end
62
-
63
- def width
64
- FORTNIGHT_SECONDS
65
- end
64
+ def width
65
+ FORTNIGHT_SECONDS
66
+ end
66
67
 
67
- def to_s
68
- super << '-fortnight'
68
+ def to_s
69
+ super << '-fortnight'
70
+ end
69
71
  end
70
- end
72
+ end