chronic 0.2.2 → 0.3.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 (57) hide show
  1. data/HISTORY.md +76 -0
  2. data/LICENSE +21 -0
  3. data/README.md +165 -0
  4. data/Rakefile +145 -18
  5. data/benchmark/benchmark.rb +13 -0
  6. data/chronic.gemspec +85 -0
  7. data/lib/chronic/chronic.rb +59 -49
  8. data/lib/chronic/grabber.rb +2 -2
  9. data/lib/chronic/handlers.rb +167 -112
  10. data/lib/{numerizer → chronic/numerizer}/numerizer.rb +17 -23
  11. data/lib/chronic/ordinal.rb +6 -6
  12. data/lib/chronic/pointer.rb +3 -3
  13. data/lib/chronic/repeater.rb +26 -12
  14. data/lib/chronic/repeaters/repeater_day.rb +17 -12
  15. data/lib/chronic/repeaters/repeater_day_name.rb +17 -12
  16. data/lib/chronic/repeaters/repeater_day_portion.rb +15 -14
  17. data/lib/chronic/repeaters/repeater_fortnight.rb +14 -9
  18. data/lib/chronic/repeaters/repeater_hour.rb +15 -10
  19. data/lib/chronic/repeaters/repeater_minute.rb +15 -10
  20. data/lib/chronic/repeaters/repeater_month.rb +20 -15
  21. data/lib/chronic/repeaters/repeater_month_name.rb +21 -16
  22. data/lib/chronic/repeaters/repeater_season.rb +136 -9
  23. data/lib/chronic/repeaters/repeater_season_name.rb +38 -17
  24. data/lib/chronic/repeaters/repeater_second.rb +15 -10
  25. data/lib/chronic/repeaters/repeater_time.rb +53 -43
  26. data/lib/chronic/repeaters/repeater_week.rb +16 -11
  27. data/lib/chronic/repeaters/repeater_weekday.rb +77 -0
  28. data/lib/chronic/repeaters/repeater_weekend.rb +14 -9
  29. data/lib/chronic/repeaters/repeater_year.rb +19 -13
  30. data/lib/chronic/scalar.rb +16 -14
  31. data/lib/chronic/separator.rb +25 -10
  32. data/lib/chronic/time_zone.rb +4 -3
  33. data/lib/chronic.rb +21 -19
  34. data/test/helper.rb +7 -0
  35. data/test/test_Chronic.rb +17 -18
  36. data/test/test_DaylightSavings.rb +118 -0
  37. data/test/test_Handler.rb +37 -38
  38. data/test/test_Numerizer.rb +8 -5
  39. data/test/test_RepeaterDayName.rb +15 -16
  40. data/test/test_RepeaterFortnight.rb +16 -17
  41. data/test/test_RepeaterHour.rb +18 -19
  42. data/test/test_RepeaterMinute.rb +34 -0
  43. data/test/test_RepeaterMonth.rb +16 -17
  44. data/test/test_RepeaterMonthName.rb +17 -18
  45. data/test/test_RepeaterTime.rb +20 -22
  46. data/test/test_RepeaterWeek.rb +16 -17
  47. data/test/test_RepeaterWeekday.rb +55 -0
  48. data/test/test_RepeaterWeekend.rb +21 -22
  49. data/test/test_RepeaterYear.rb +17 -18
  50. data/test/test_Span.rb +5 -6
  51. data/test/test_Time.rb +11 -12
  52. data/test/test_Token.rb +5 -6
  53. data/test/test_parsing.rb +314 -196
  54. metadata +74 -49
  55. data/History.txt +0 -49
  56. data/README.txt +0 -149
  57. data/test/suite.rb +0 -9
@@ -8,7 +8,7 @@ module Chronic
8
8
  end
9
9
  tokens
10
10
  end
11
-
11
+
12
12
  def self.scan_for_all(token)
13
13
  scanner = {/\bpast\b/ => :past,
14
14
  /\bfuture\b/ => :future,
@@ -18,10 +18,10 @@ module Chronic
18
18
  end
19
19
  return nil
20
20
  end
21
-
21
+
22
22
  def to_s
23
23
  'pointer-' << @type.to_s
24
24
  end
25
25
  end
26
26
 
27
- end
27
+ end
@@ -2,6 +2,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
2
2
  def self.scan(tokens, options)
3
3
  # for each token
4
4
  tokens.each_index do |i|
5
+ if t = self.scan_for_season_names(tokens[i]) then tokens[i].tag(t); next end
5
6
  if t = self.scan_for_month_names(tokens[i]) then tokens[i].tag(t); next end
6
7
  if t = self.scan_for_day_names(tokens[i]) then tokens[i].tag(t); next end
7
8
  if t = self.scan_for_day_portions(tokens[i]) then tokens[i].tag(t); next end
@@ -10,7 +11,19 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
10
11
  end
11
12
  tokens
12
13
  end
13
-
14
+
15
+ def self.scan_for_season_names(token)
16
+ scanner = {/^springs?$/ => :spring,
17
+ /^summers?$/ => :summer,
18
+ /^(autumn)|(fall)s?$/ => :autumn,
19
+ /^winters?$/ => :winter}
20
+ scanner.keys.each do |scanner_item|
21
+ return Chronic::RepeaterSeasonName.new(scanner[scanner_item]) if scanner_item =~ token.word
22
+ end
23
+
24
+ return nil
25
+ end
26
+
14
27
  def self.scan_for_month_names(token)
15
28
  scanner = {/^jan\.?(uary)?$/ => :january,
16
29
  /^feb\.?(ruary)?$/ => :february,
@@ -29,7 +42,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
29
42
  end
30
43
  return nil
31
44
  end
32
-
45
+
33
46
  def self.scan_for_day_names(token)
34
47
  scanner = {/^m[ou]n(day)?$/ => :monday,
35
48
  /^t(ue|eu|oo|u|)s(day)?$/ => :tuesday,
@@ -46,7 +59,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
46
59
  end
47
60
  return nil
48
61
  end
49
-
62
+
50
63
  def self.scan_for_day_portions(token)
51
64
  scanner = {/^ams?$/ => :am,
52
65
  /^pms?$/ => :pm,
@@ -59,14 +72,14 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
59
72
  end
60
73
  return nil
61
74
  end
62
-
75
+
63
76
  def self.scan_for_times(token, options)
64
77
  if token.word =~ /^\d{1,2}(:?\d{2})?([\.:]?\d{2})?$/
65
78
  return Chronic::RepeaterTime.new(token.word, options)
66
79
  end
67
80
  return nil
68
81
  end
69
-
82
+
70
83
  def self.scan_for_units(token)
71
84
  scanner = {/^years?$/ => :year,
72
85
  /^seasons?$/ => :season,
@@ -74,6 +87,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
74
87
  /^fortnights?$/ => :fortnight,
75
88
  /^weeks?$/ => :week,
76
89
  /^weekends?$/ => :weekend,
90
+ /^(week|business)days?$/ => :weekday,
77
91
  /^days?$/ => :day,
78
92
  /^hours?$/ => :hour,
79
93
  /^minutes?$/ => :minute,
@@ -82,34 +96,34 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
82
96
  if scanner_item =~ token.word
83
97
  klass_name = 'Chronic::Repeater' + scanner[scanner_item].to_s.capitalize
84
98
  klass = eval(klass_name)
85
- return klass.new(scanner[scanner_item])
99
+ return klass.new(scanner[scanner_item])
86
100
  end
87
101
  end
88
102
  return nil
89
103
  end
90
-
104
+
91
105
  def <=>(other)
92
106
  width <=> other.width
93
107
  end
94
-
108
+
95
109
  # returns the width (in seconds or months) of this repeatable.
96
110
  def width
97
111
  raise("Repeatable#width must be overridden in subclasses")
98
112
  end
99
-
113
+
100
114
  # returns the next occurance of this repeatable.
101
115
  def next(pointer)
102
116
  !@now.nil? || raise("Start point must be set before calling #next")
103
117
  [:future, :none, :past].include?(pointer) || raise("First argument 'pointer' must be one of :past or :future")
104
118
  #raise("Repeatable#next must be overridden in subclasses")
105
119
  end
106
-
120
+
107
121
  def this(pointer)
108
122
  !@now.nil? || raise("Start point must be set before calling #this")
109
123
  [:future, :past, :none].include?(pointer) || raise("First argument 'pointer' must be one of :past, :future, :none")
110
124
  end
111
-
125
+
112
126
  def to_s
113
127
  'repeater'
114
128
  end
115
- end
129
+ end
@@ -1,22 +1,27 @@
1
1
  class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
2
2
  DAY_SECONDS = 86_400 # (24 * 60 * 60)
3
-
3
+
4
+ def initialize(type)
5
+ super
6
+ @current_day_start = nil
7
+ end
8
+
4
9
  def next(pointer)
5
10
  super
6
-
11
+
7
12
  if !@current_day_start
8
- @current_day_start = Time.local(@now.year, @now.month, @now.day)
13
+ @current_day_start = Chronic.time_class.local(@now.year, @now.month, @now.day)
9
14
  end
10
-
15
+
11
16
  direction = pointer == :future ? 1 : -1
12
17
  @current_day_start += direction * DAY_SECONDS
13
-
18
+
14
19
  Chronic::Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
15
20
  end
16
-
21
+
17
22
  def this(pointer = :future)
18
23
  super
19
-
24
+
20
25
  case pointer
21
26
  when :future
22
27
  day_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
@@ -28,20 +33,20 @@ class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
28
33
  day_begin = Time.construct(@now.year, @now.month, @now.day)
29
34
  day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
30
35
  end
31
-
36
+
32
37
  Chronic::Span.new(day_begin, day_end)
33
38
  end
34
-
39
+
35
40
  def offset(span, amount, pointer)
36
41
  direction = pointer == :future ? 1 : -1
37
42
  span + direction * amount * DAY_SECONDS
38
43
  end
39
-
44
+
40
45
  def width
41
46
  DAY_SECONDS
42
47
  end
43
-
48
+
44
49
  def to_s
45
50
  super << '-day'
46
51
  end
47
- end
52
+ end
@@ -1,46 +1,51 @@
1
1
  class Chronic::RepeaterDayName < Chronic::Repeater #:nodoc:
2
2
  DAY_SECONDS = 86400 # (24 * 60 * 60)
3
-
3
+
4
+ def initialize(type)
5
+ super
6
+ @current_day_start = nil
7
+ end
8
+
4
9
  def next(pointer)
5
10
  super
6
-
11
+
7
12
  direction = pointer == :future ? 1 : -1
8
-
13
+
9
14
  if !@current_day_start
10
15
  @current_day_start = Time.construct(@now.year, @now.month, @now.day)
11
16
  @current_day_start += direction * DAY_SECONDS
12
17
 
13
18
  day_num = symbol_to_number(@type)
14
-
19
+
15
20
  while @current_day_start.wday != day_num
16
21
  @current_day_start += direction * DAY_SECONDS
17
22
  end
18
23
  else
19
24
  @current_day_start += direction * 7 * DAY_SECONDS
20
25
  end
21
-
26
+
22
27
  Chronic::Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
23
28
  end
24
-
29
+
25
30
  def this(pointer = :future)
26
31
  super
27
-
32
+
28
33
  pointer = :future if pointer == :none
29
34
  self.next(pointer)
30
35
  end
31
-
36
+
32
37
  def width
33
38
  DAY_SECONDS
34
39
  end
35
-
40
+
36
41
  def to_s
37
42
  super << '-dayname-' << @type.to_s
38
43
  end
39
-
44
+
40
45
  private
41
-
46
+
42
47
  def symbol_to_number(sym)
43
48
  lookup = {:sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3, :thursday => 4, :friday => 5, :saturday => 6}
44
49
  lookup[sym] || raise("Invalid symbol specified")
45
50
  end
46
- end
51
+ end
@@ -3,15 +3,16 @@ class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
3
3
  @@afternoon = (13 * 60 * 60)..(17 * 60 * 60) # 1pm-5pm
4
4
  @@evening = (17 * 60 * 60)..(20 * 60 * 60) # 5pm-8pm
5
5
  @@night = (20 * 60 * 60)..(24 * 60 * 60) # 8pm-12pm
6
-
6
+
7
7
  def initialize(type)
8
8
  super
9
-
9
+ @current_span = nil
10
+
10
11
  if type.kind_of? Integer
11
12
  @range = (@type * 60 * 60)..((@type + 12) * 60 * 60)
12
13
  else
13
- lookup = {:am => 1..(12 * 60 * 60),
14
- :pm => (12 * 60 * 60)..(24 * 60 * 60),
14
+ lookup = {:am => 0..(12 * 60 * 60 - 1),
15
+ :pm => (12 * 60 * 60)..(24 * 60 * 60 - 1),
15
16
  :morning => @@morning,
16
17
  :afternoon => @@afternoon,
17
18
  :evening => @@evening,
@@ -21,12 +22,12 @@ class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
21
22
  end
22
23
  @range || raise("Range should have been set by now")
23
24
  end
24
-
25
+
25
26
  def next(pointer)
26
27
  super
27
-
28
+
28
29
  full_day = 60 * 60 * 24
29
-
30
+
30
31
  if !@current_span
31
32
  now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
32
33
  if now_seconds < @range.begin
@@ -51,7 +52,7 @@ class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
51
52
  range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
52
53
  end
53
54
  end
54
-
55
+
55
56
  @current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
56
57
  else
57
58
  case pointer
@@ -62,21 +63,21 @@ class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
62
63
  end
63
64
  end
64
65
  end
65
-
66
+
66
67
  def this(context = :future)
67
68
  super
68
-
69
+
69
70
  range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
70
71
  @current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
71
72
  end
72
-
73
+
73
74
  def offset(span, amount, pointer)
74
75
  @now = span.begin
75
76
  portion_span = self.next(pointer)
76
77
  direction = pointer == :future ? 1 : -1
77
78
  portion_span + (direction * (amount - 1) * Chronic::RepeaterDay::DAY_SECONDS)
78
79
  end
79
-
80
+
80
81
  def width
81
82
  @range || raise("Range has not been set")
82
83
  return @current_span.width if @current_span
@@ -86,8 +87,8 @@ class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
86
87
  @range.end - @range.begin
87
88
  end
88
89
  end
89
-
90
+
90
91
  def to_s
91
92
  super << '-dayportion-' << @type.to_s
92
93
  end
93
- end
94
+ end
@@ -1,9 +1,14 @@
1
1
  class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
2
2
  FORTNIGHT_SECONDS = 1_209_600 # (14 * 24 * 60 * 60)
3
-
3
+
4
+ def initialize(type)
5
+ super
6
+ @current_fortnight_start = nil
7
+ end
8
+
4
9
  def next(pointer)
5
10
  super
6
-
11
+
7
12
  if !@current_fortnight_start
8
13
  case pointer
9
14
  when :future
@@ -22,15 +27,15 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
22
27
  direction = pointer == :future ? 1 : -1
23
28
  @current_fortnight_start += direction * FORTNIGHT_SECONDS
24
29
  end
25
-
30
+
26
31
  Chronic::Span.new(@current_fortnight_start, @current_fortnight_start + FORTNIGHT_SECONDS)
27
32
  end
28
-
33
+
29
34
  def this(pointer = :future)
30
35
  super
31
-
36
+
32
37
  pointer = :future if pointer == :none
33
-
38
+
34
39
  case pointer
35
40
  when :future
36
41
  this_fortnight_start = Time.construct(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
@@ -49,7 +54,7 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
49
54
  Chronic::Span.new(this_fortnight_start, this_fortnight_end)
50
55
  end
51
56
  end
52
-
57
+
53
58
  def offset(span, amount, pointer)
54
59
  direction = pointer == :future ? 1 : -1
55
60
  span + direction * amount * FORTNIGHT_SECONDS
@@ -58,8 +63,8 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
58
63
  def width
59
64
  FORTNIGHT_SECONDS
60
65
  end
61
-
66
+
62
67
  def to_s
63
68
  super << '-fortnight'
64
69
  end
65
- end
70
+ end
@@ -1,9 +1,14 @@
1
1
  class Chronic::RepeaterHour < Chronic::Repeater #:nodoc:
2
2
  HOUR_SECONDS = 3600 # 60 * 60
3
-
3
+
4
+ def initialize(type)
5
+ super
6
+ @current_hour_start = nil
7
+ end
8
+
4
9
  def next(pointer)
5
10
  super
6
-
11
+
7
12
  if !@current_hour_start
8
13
  case pointer
9
14
  when :future
@@ -15,13 +20,13 @@ class Chronic::RepeaterHour < Chronic::Repeater #:nodoc:
15
20
  direction = pointer == :future ? 1 : -1
16
21
  @current_hour_start += direction * HOUR_SECONDS
17
22
  end
18
-
23
+
19
24
  Chronic::Span.new(@current_hour_start, @current_hour_start + HOUR_SECONDS)
20
25
  end
21
-
26
+
22
27
  def this(pointer = :future)
23
28
  super
24
-
29
+
25
30
  case pointer
26
31
  when :future
27
32
  hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
@@ -33,20 +38,20 @@ class Chronic::RepeaterHour < Chronic::Repeater #:nodoc:
33
38
  hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour)
34
39
  hour_end = hour_begin + HOUR_SECONDS
35
40
  end
36
-
41
+
37
42
  Chronic::Span.new(hour_start, hour_end)
38
43
  end
39
-
44
+
40
45
  def offset(span, amount, pointer)
41
46
  direction = pointer == :future ? 1 : -1
42
47
  span + direction * amount * HOUR_SECONDS
43
48
  end
44
-
49
+
45
50
  def width
46
51
  HOUR_SECONDS
47
52
  end
48
-
53
+
49
54
  def to_s
50
55
  super << '-hour'
51
56
  end
52
- end
57
+ end
@@ -1,9 +1,14 @@
1
1
  class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
2
2
  MINUTE_SECONDS = 60
3
-
3
+
4
+ def initialize(type)
5
+ super
6
+ @current_minute_start = nil
7
+ end
8
+
4
9
  def next(pointer = :future)
5
10
  super
6
-
11
+
7
12
  if !@current_minute_start
8
13
  case pointer
9
14
  when :future
@@ -15,13 +20,13 @@ class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
15
20
  direction = pointer == :future ? 1 : -1
16
21
  @current_minute_start += direction * MINUTE_SECONDS
17
22
  end
18
-
23
+
19
24
  Chronic::Span.new(@current_minute_start, @current_minute_start + MINUTE_SECONDS)
20
25
  end
21
-
26
+
22
27
  def this(pointer = :future)
23
28
  super
24
-
29
+
25
30
  case pointer
26
31
  when :future
27
32
  minute_begin = @now
@@ -33,20 +38,20 @@ class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
33
38
  minute_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
34
39
  minute_end = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
35
40
  end
36
-
41
+
37
42
  Chronic::Span.new(minute_begin, minute_end)
38
43
  end
39
-
44
+
40
45
  def offset(span, amount, pointer)
41
46
  direction = pointer == :future ? 1 : -1
42
47
  span + direction * amount * MINUTE_SECONDS
43
48
  end
44
-
49
+
45
50
  def width
46
51
  MINUTE_SECONDS
47
52
  end
48
-
53
+
49
54
  def to_s
50
55
  super << '-minute'
51
56
  end
52
- end
57
+ end
@@ -1,22 +1,27 @@
1
1
  class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
2
2
  MONTH_SECONDS = 2_592_000 # 30 * 24 * 60 * 60
3
3
  YEAR_MONTHS = 12
4
-
4
+
5
+ def initialize(type)
6
+ super
7
+ @current_month_start = nil
8
+ end
9
+
5
10
  def next(pointer)
6
11
  super
7
-
12
+
8
13
  if !@current_month_start
9
14
  @current_month_start = offset_by(Time.construct(@now.year, @now.month), 1, pointer)
10
15
  else
11
16
  @current_month_start = offset_by(Time.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
12
17
  end
13
-
18
+
14
19
  Chronic::Span.new(@current_month_start, Time.construct(@current_month_start.year, @current_month_start.month + 1))
15
20
  end
16
-
21
+
17
22
  def this(pointer = :future)
18
23
  super
19
-
24
+
20
25
  case pointer
21
26
  when :future
22
27
  month_start = Time.construct(@now.year, @now.month, @now.day + 1)
@@ -28,20 +33,20 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
28
33
  month_start = Time.construct(@now.year, @now.month)
29
34
  month_end = self.offset_by(Time.construct(@now.year, @now.month), 1, :future)
30
35
  end
31
-
36
+
32
37
  Chronic::Span.new(month_start, month_end)
33
38
  end
34
-
35
- def offset(span, amount, pointer)
39
+
40
+ def offset(span, amount, pointer)
36
41
  Chronic::Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
37
42
  end
38
-
39
- def offset_by(time, amount, pointer)
43
+
44
+ def offset_by(time, amount, pointer)
40
45
  direction = pointer == :future ? 1 : -1
41
-
46
+
42
47
  amount_years = direction * amount / YEAR_MONTHS
43
48
  amount_months = direction * amount % YEAR_MONTHS
44
-
49
+
45
50
  new_year = time.year + amount_years
46
51
  new_month = time.month + amount_months
47
52
  if new_month > YEAR_MONTHS
@@ -50,12 +55,12 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
50
55
  end
51
56
  Time.construct(new_year, new_month, time.day, time.hour, time.min, time.sec)
52
57
  end
53
-
58
+
54
59
  def width
55
60
  MONTH_SECONDS
56
61
  end
57
-
62
+
58
63
  def to_s
59
64
  super << '-month'
60
65
  end
61
- end
66
+ end
@@ -1,28 +1,33 @@
1
1
  class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
2
2
  MONTH_SECONDS = 2_592_000 # 30 * 24 * 60 * 60
3
-
3
+
4
+ def initialize(type)
5
+ super
6
+ @current_month_begin = nil
7
+ end
8
+
4
9
  def next(pointer)
5
10
  super
6
-
11
+
7
12
  if !@current_month_begin
8
13
  target_month = symbol_to_number(@type)
9
14
  case pointer
10
15
  when :future
11
16
  if @now.month < target_month
12
17
  @current_month_begin = Time.construct(@now.year, target_month)
13
- else @now.month > target_month
18
+ elsif @now.month > target_month
14
19
  @current_month_begin = Time.construct(@now.year + 1, target_month)
15
20
  end
16
21
  when :none
17
22
  if @now.month <= target_month
18
23
  @current_month_begin = Time.construct(@now.year, target_month)
19
- else @now.month > target_month
24
+ elsif @now.month > target_month
20
25
  @current_month_begin = Time.construct(@now.year + 1, target_month)
21
26
  end
22
27
  when :past
23
28
  if @now.month > target_month
24
29
  @current_month_begin = Time.construct(@now.year, target_month)
25
- else @now.month < target_month
30
+ elsif @now.month < target_month
26
31
  @current_month_begin = Time.construct(@now.year - 1, target_month)
27
32
  end
28
33
  end
@@ -35,10 +40,10 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
35
40
  @current_month_begin = Time.construct(@current_month_begin.year - 1, @current_month_begin.month)
36
41
  end
37
42
  end
38
-
43
+
39
44
  cur_month_year = @current_month_begin.year
40
45
  cur_month_month = @current_month_begin.month
41
-
46
+
42
47
  if cur_month_month == 12
43
48
  next_month_year = cur_month_year + 1
44
49
  next_month_month = 1
@@ -46,13 +51,13 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
46
51
  next_month_year = cur_month_year
47
52
  next_month_month = cur_month_month + 1
48
53
  end
49
-
54
+
50
55
  Chronic::Span.new(@current_month_begin, Time.construct(next_month_year, next_month_month))
51
56
  end
52
-
57
+
53
58
  def this(pointer = :future)
54
59
  super
55
-
60
+
56
61
  case pointer
57
62
  when :past
58
63
  self.next(pointer)
@@ -60,21 +65,21 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
60
65
  self.next(:none)
61
66
  end
62
67
  end
63
-
68
+
64
69
  def width
65
70
  MONTH_SECONDS
66
71
  end
67
-
72
+
68
73
  def index
69
74
  symbol_to_number(@type)
70
75
  end
71
-
76
+
72
77
  def to_s
73
78
  super << '-monthname-' << @type.to_s
74
79
  end
75
-
80
+
76
81
  private
77
-
82
+
78
83
  def symbol_to_number(sym)
79
84
  lookup = {:january => 1,
80
85
  :february => 2,
@@ -90,4 +95,4 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
90
95
  :december => 12}
91
96
  lookup[sym] || raise("Invalid symbol specified")
92
97
  end
93
- end
98
+ end