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,150 +1,128 @@
1
- class Time
2
- def to_minidate
3
- MiniDate.new(self.month, self.day)
4
- end
5
- end
6
-
7
- class Season
8
- attr_reader :start, :end
9
-
10
- def initialize(myStart, myEnd)
11
- @start = myStart
12
- @end = myEnd
13
- end
1
+ module Chronic
2
+ class Season
3
+ attr_reader :start, :end
14
4
 
15
- def self.find_next_season(season, pointer)
16
- lookup = {:spring => 0, :summer => 1, :autumn => 2, :winter => 3}
17
- next_season_num = (lookup[season]+1*pointer) % 4
18
- lookup.invert[next_season_num]
19
- end
20
-
21
- def self.season_after(season); find_next_season(season, +1); end
22
- def self.season_before(season); find_next_season(season, -1); end
23
- end
5
+ def initialize(myStart, myEnd)
6
+ @start = myStart
7
+ @end = myEnd
8
+ end
24
9
 
25
- class MiniDate
26
- attr_accessor :month, :day
10
+ def self.find_next_season(season, pointer)
11
+ lookup = {:spring => 0, :summer => 1, :autumn => 2, :winter => 3}
12
+ next_season_num = (lookup[season]+1*pointer) % 4
13
+ lookup.invert[next_season_num]
14
+ end
27
15
 
28
- def initialize(month, day)
29
- @month = month
30
- @day = day
16
+ def self.season_after(season); find_next_season(season, +1); end
17
+ def self.season_before(season); find_next_season(season, -1); end
31
18
  end
32
19
 
33
- def is_between?(md_start, md_end)
34
- return true if (@month == md_start.month and @day >= md_start.day) ||
35
- (@month == md_end.month and @day <= md_end.day)
20
+ class RepeaterSeason < Repeater #:nodoc:
21
+ SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
22
+ SEASONS = {
23
+ :spring => Season.new(MiniDate.new(3,20), MiniDate.new(6,20)),
24
+ :summer => Season.new(MiniDate.new(6,21), MiniDate.new(9,22)),
25
+ :autumn => Season.new(MiniDate.new(9,23), MiniDate.new(12,21)),
26
+ :winter => Season.new(MiniDate.new(12,22), MiniDate.new(3,19))
27
+ }
36
28
 
37
- i = md_start.month + 1
38
- until i == md_end.month
39
- return true if @month == i
40
- i = (i+1) % 12
29
+ def initialize(type)
30
+ super
31
+ @next_season_start = nil
41
32
  end
42
33
 
43
- return false
44
- end
34
+ def next(pointer)
35
+ super
45
36
 
46
- def equals?(other)
47
- @month == other.month and day == other.day
48
- end
49
- end
50
-
51
- class Chronic::RepeaterSeason < Chronic::Repeater #:nodoc:
52
- YEAR_SEASONS = 4
53
- SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
54
- SEASONS = { :spring => Season.new( MiniDate.new(3,20),MiniDate.new(6,20) ),
55
- :summer => Season.new( MiniDate.new(6,21),MiniDate.new(9,22) ),
56
- :autumn => Season.new( MiniDate.new(9,23),MiniDate.new(12,21) ),
57
- :winter => Season.new( MiniDate.new(12,22),MiniDate.new(3,19) ) }
58
-
59
- def initialize(type)
60
- super
61
- @next_season_start = nil
62
- end
37
+ direction = pointer == :future ? 1 : -1
38
+ next_season = Season.find_next_season(find_current_season(@now.to_minidate), direction)
63
39
 
64
- def next(pointer)
65
- super
40
+ find_next_season_span(direction, next_season)
41
+ end
66
42
 
67
- direction = pointer == :future ? 1 : -1
68
- next_season = Season.find_next_season(find_current_season(@now.to_minidate), direction)
43
+ def this(pointer = :future)
44
+ super
45
+
46
+ direction = pointer == :future ? 1 : -1
47
+
48
+ today = Time.construct(@now.year, @now.month, @now.day)
49
+ this_ssn = find_current_season(@now.to_minidate)
50
+ case pointer
51
+ when :past
52
+ this_ssn_start = today + direction * num_seconds_til_start(this_ssn, direction)
53
+ this_ssn_end = today
54
+ when :future
55
+ this_ssn_start = today + RepeaterDay::DAY_SECONDS
56
+ this_ssn_end = today + direction * num_seconds_til_end(this_ssn, direction)
57
+ when :none
58
+ this_ssn_start = today + direction * num_seconds_til_start(this_ssn, direction)
59
+ this_ssn_end = today + direction * num_seconds_til_end(this_ssn, direction)
60
+ end
61
+
62
+ construct_season(this_ssn_start, this_ssn_end)
63
+ end
69
64
 
70
- find_next_season_span(direction, next_season)
71
- end
65
+ def offset(span, amount, pointer)
66
+ Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
67
+ end
72
68
 
73
- def this(pointer = :future)
74
- super
75
-
76
- direction = pointer == :future ? 1 : -1
77
-
78
- today = Time.construct(@now.year, @now.month, @now.day)
79
- this_ssn = find_current_season(@now.to_minidate)
80
- case pointer
81
- when :past
82
- this_ssn_start = today + direction * num_seconds_til_start(this_ssn, direction)
83
- this_ssn_end = today
84
- when :future
85
- this_ssn_start = today + Chronic::RepeaterDay::DAY_SECONDS
86
- this_ssn_end = today + direction * num_seconds_til_end(this_ssn, direction)
87
- when :none
88
- this_ssn_start = today + direction * num_seconds_til_start(this_ssn, direction)
89
- this_ssn_end = today + direction * num_seconds_til_end(this_ssn, direction)
69
+ def offset_by(time, amount, pointer)
70
+ direction = pointer == :future ? 1 : -1
71
+ time + amount * direction * SEASON_SECONDS
90
72
  end
91
73
 
92
- Chronic::Span.new(this_ssn_start, this_ssn_end)
93
- end
74
+ def width
75
+ SEASON_SECONDS
76
+ end
94
77
 
95
- def offset(span, amount, pointer)
96
- Chronic::Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
97
- end
78
+ def to_s
79
+ super << '-season'
80
+ end
98
81
 
99
- def offset_by(time, amount, pointer)
100
- direction = pointer == :future ? 1 : -1
101
- time + amount * direction * SEASON_SECONDS
102
- end
82
+ private
103
83
 
104
- def width
105
- SEASON_SECONDS
106
- end
84
+ def find_next_season_span(direction, next_season)
85
+ if !@next_season_start or !@next_season_end
86
+ @next_season_start = Time.construct(@now.year, @now.month, @now.day)
87
+ @next_season_end = Time.construct(@now.year, @now.month, @now.day)
88
+ end
107
89
 
108
- def to_s
109
- super << '-season'
110
- end
90
+ @next_season_start += direction * num_seconds_til_start(next_season, direction)
91
+ @next_season_end += direction * num_seconds_til_end(next_season, direction)
111
92
 
112
- private
93
+ construct_season(@next_season_start, @next_season_end)
94
+ end
113
95
 
114
- def find_next_season_span(direction, next_season)
115
- if !@next_season_start or !@next_season_end
116
- @next_season_start = Time.construct(@now.year, @now.month, @now.day)
117
- @next_season_end = Time.construct(@now.year, @now.month, @now.day)
96
+ def find_current_season(md)
97
+ [:spring, :summer, :autumn, :winter].find do |season|
98
+ md.is_between?(SEASONS[season].start, SEASONS[season].end)
99
+ end
118
100
  end
119
101
 
120
- @next_season_start += direction * num_seconds_til_start(next_season, direction)
121
- @next_season_end += direction * num_seconds_til_end(next_season, direction)
102
+ def num_seconds_til(goal, direction)
103
+ start = Time.construct(@now.year, @now.month, @now.day)
104
+ seconds = 0
122
105
 
123
- Chronic::Span.new(@next_season_start, @next_season_end)
124
- end
106
+ until (start + direction * seconds).to_minidate.equals?(goal)
107
+ seconds += RepeaterDay::DAY_SECONDS
108
+ end
125
109
 
126
- def find_current_season(md)
127
- [:spring, :summer, :autumn, :winter].each do |season|
128
- return season if md.is_between?(SEASONS[season].start, SEASONS[season].end)
110
+ seconds
129
111
  end
130
- end
131
-
132
- def num_seconds_til(goal, direction)
133
- start = Time.construct(@now.year, @now.month, @now.day)
134
- seconds = 0
135
112
 
136
- until (start + direction * seconds).to_minidate.equals?(goal)
137
- seconds += Chronic::RepeaterDay::DAY_SECONDS
113
+ def num_seconds_til_start(season_symbol, direction)
114
+ num_seconds_til(SEASONS[season_symbol].start, direction)
138
115
  end
139
116
 
140
- seconds
141
- end
142
-
143
- def num_seconds_til_start(season_symbol, direction)
144
- num_seconds_til(SEASONS[season_symbol].start, direction)
145
- end
117
+ def num_seconds_til_end(season_symbol, direction)
118
+ num_seconds_til(SEASONS[season_symbol].end, direction)
119
+ end
146
120
 
147
- def num_seconds_til_end(season_symbol, direction)
148
- num_seconds_til(SEASONS[season_symbol].end, direction)
121
+ def construct_season(start, finish)
122
+ Span.new(
123
+ Time.construct(start.year, start.month, start.day),
124
+ Time.construct(finish.year, finish.month, finish.day)
125
+ )
126
+ end
149
127
  end
150
- end
128
+ end
@@ -1,45 +1,45 @@
1
- require 'chronic/repeaters/repeater_season.rb'
2
-
3
- class Chronic::RepeaterSeasonName < Chronic::RepeaterSeason #:nodoc:
4
- SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
5
- DAY_SECONDS = 86_400 # (24 * 60 * 60)
6
-
7
- def next(pointer)
8
- direction = pointer == :future ? 1 : -1
9
- find_next_season_span(direction, @type)
10
- end
1
+ module Chronic
2
+ class RepeaterSeasonName < RepeaterSeason #:nodoc:
3
+ SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
4
+ DAY_SECONDS = 86_400 # (24 * 60 * 60)
5
+
6
+ def next(pointer)
7
+ direction = pointer == :future ? 1 : -1
8
+ find_next_season_span(direction, @type)
9
+ end
11
10
 
12
- def this(pointer = :future)
13
- # super
14
-
15
- direction = pointer == :future ? 1 : -1
16
-
17
- today = Time.construct(@now.year, @now.month, @now.day)
18
- goal_ssn_start = today + direction * num_seconds_til_start(@type, direction)
19
- goal_ssn_end = today + direction * num_seconds_til_end(@type, direction)
20
- curr_ssn = find_current_season(@now.to_minidate)
21
- case pointer
22
- when :past
23
- this_ssn_start = goal_ssn_start
24
- this_ssn_end = (curr_ssn == @type) ? today : goal_ssn_end
25
- when :future
26
- this_ssn_start = (curr_ssn == @type) ? today + Chronic::RepeaterDay::DAY_SECONDS : goal_ssn_start
27
- this_ssn_end = goal_ssn_end
28
- when :none
29
- this_ssn_start = goal_ssn_start
30
- this_ssn_end = goal_ssn_end
11
+ def this(pointer = :future)
12
+ # super
13
+
14
+ direction = pointer == :future ? 1 : -1
15
+
16
+ today = Time.construct(@now.year, @now.month, @now.day)
17
+ goal_ssn_start = today + direction * num_seconds_til_start(@type, direction)
18
+ goal_ssn_end = today + direction * num_seconds_til_end(@type, direction)
19
+ curr_ssn = find_current_season(@now.to_minidate)
20
+ case pointer
21
+ when :past
22
+ this_ssn_start = goal_ssn_start
23
+ this_ssn_end = (curr_ssn == @type) ? today : goal_ssn_end
24
+ when :future
25
+ this_ssn_start = (curr_ssn == @type) ? today + RepeaterDay::DAY_SECONDS : goal_ssn_start
26
+ this_ssn_end = goal_ssn_end
27
+ when :none
28
+ this_ssn_start = goal_ssn_start
29
+ this_ssn_end = goal_ssn_end
30
+ end
31
+
32
+ construct_season(this_ssn_start, this_ssn_end)
31
33
  end
32
34
 
33
- Chronic::Span.new(this_ssn_start, this_ssn_end)
34
- end
35
+ def offset(span, amount, pointer)
36
+ Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
37
+ end
35
38
 
36
- def offset(span, amount, pointer)
37
- Chronic::Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
38
- end
39
+ def offset_by(time, amount, pointer)
40
+ direction = pointer == :future ? 1 : -1
41
+ time + amount * direction * RepeaterYear::YEAR_SECONDS
42
+ end
39
43
 
40
- def offset_by(time, amount, pointer)
41
- direction = pointer == :future ? 1 : -1
42
- time + amount * direction * Chronic::RepeaterYear::YEAR_SECONDS
43
44
  end
44
-
45
- end
45
+ end
@@ -1,41 +1,43 @@
1
- class Chronic::RepeaterSecond < Chronic::Repeater #:nodoc:
2
- SECOND_SECONDS = 1 # haha, awesome
1
+ module Chronic
2
+ class RepeaterSecond < Repeater #:nodoc:
3
+ SECOND_SECONDS = 1 # haha, awesome
3
4
 
4
- def initialize(type)
5
- super
6
- @second_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @second_start = nil
8
+ end
8
9
 
9
- def next(pointer = :future)
10
- super
10
+ def next(pointer = :future)
11
+ super
11
12
 
12
- direction = pointer == :future ? 1 : -1
13
+ direction = pointer == :future ? 1 : -1
13
14
 
14
- if !@second_start
15
- @second_start = @now + (direction * SECOND_SECONDS)
16
- else
17
- @second_start += SECOND_SECONDS * direction
18
- end
15
+ if !@second_start
16
+ @second_start = @now + (direction * SECOND_SECONDS)
17
+ else
18
+ @second_start += SECOND_SECONDS * direction
19
+ end
19
20
 
20
- Chronic::Span.new(@second_start, @second_start + SECOND_SECONDS)
21
- end
21
+ Span.new(@second_start, @second_start + SECOND_SECONDS)
22
+ end
22
23
 
23
- def this(pointer = :future)
24
- super
24
+ def this(pointer = :future)
25
+ super
25
26
 
26
- Chronic::Span.new(@now, @now + 1)
27
- end
27
+ Span.new(@now, @now + 1)
28
+ end
28
29
 
29
- def offset(span, amount, pointer)
30
- direction = pointer == :future ? 1 : -1
31
- span + direction * amount * SECOND_SECONDS
32
- end
30
+ def offset(span, amount, pointer)
31
+ direction = pointer == :future ? 1 : -1
32
+ span + direction * amount * SECOND_SECONDS
33
+ end
33
34
 
34
- def width
35
- SECOND_SECONDS
36
- end
35
+ def width
36
+ SECOND_SECONDS
37
+ end
37
38
 
38
- def to_s
39
- super << '-second'
39
+ def to_s
40
+ super << '-second'
41
+ end
40
42
  end
41
- end
43
+ end
@@ -1,124 +1,129 @@
1
- class Chronic::RepeaterTime < Chronic::Repeater #:nodoc:
2
- class Tick #:nodoc:
3
- attr_accessor :time
1
+ module Chronic
2
+ class RepeaterTime < Repeater #:nodoc:
3
+ class Tick #:nodoc:
4
+ attr_accessor :time
5
+
6
+ def initialize(time, ambiguous = false)
7
+ @time = time
8
+ @ambiguous = ambiguous
9
+ end
4
10
 
5
- def initialize(time, ambiguous = false)
6
- @time = time
7
- @ambiguous = ambiguous
8
- end
11
+ def ambiguous?
12
+ @ambiguous
13
+ end
9
14
 
10
- def ambiguous?
11
- @ambiguous
12
- end
15
+ def *(other)
16
+ Tick.new(@time * other, @ambiguous)
17
+ end
13
18
 
14
- def *(other)
15
- Tick.new(@time * other, @ambiguous)
16
- end
19
+ def to_f
20
+ @time.to_f
21
+ end
17
22
 
18
- def to_f
19
- @time.to_f
20
- end
23
+ def to_s
24
+ @time.to_s + (@ambiguous ? '?' : '')
25
+ end
21
26
 
22
- def to_s
23
- @time.to_s + (@ambiguous ? '?' : '')
24
27
  end
25
- end
26
28
 
27
- def initialize(time, options = {})
28
- @current_time = nil
29
- t = time.gsub(/\:/, '')
30
-
31
- @type =
32
- case t.size
33
- when 1..2
34
- hours = t.to_i
35
- hours == 12 ? Tick.new(0 * 60 * 60, true) : Tick.new(hours * 60 * 60, true)
36
- when 3
37
- Tick.new((t[0..0].to_i * 60 * 60) + (t[1..2].to_i * 60), true)
38
- when 4
39
- ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
40
- hours = t[0..1].to_i
41
- hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60, ambiguous)
42
- when 5
43
- Tick.new(t[0..0].to_i * 60 * 60 + t[1..2].to_i * 60 + t[3..4].to_i, true)
44
- when 6
45
- ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
46
- hours = t[0..1].to_i
47
- hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous)
48
- else
49
- raise("Time cannot exceed six digits")
29
+ def initialize(time)
30
+ @current_time = nil
31
+ t = time.gsub(/\:/, '')
32
+
33
+ @type =
34
+ case t.size
35
+ when 1..2
36
+ hours = t.to_i
37
+ hours == 12 ? Tick.new(0 * 60 * 60, true) : Tick.new(hours * 60 * 60, true)
38
+ when 3
39
+ hours = t[0..0].to_i
40
+ ambiguous = hours > 1
41
+ Tick.new((hours * 60 * 60) + (t[1..2].to_i * 60), ambiguous)
42
+ when 4
43
+ ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
44
+ hours = t[0..1].to_i
45
+ hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60, ambiguous)
46
+ when 5
47
+ Tick.new(t[0..0].to_i * 60 * 60 + t[1..2].to_i * 60 + t[3..4].to_i, true)
48
+ when 6
49
+ ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
50
+ hours = t[0..1].to_i
51
+ hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous)
52
+ else
53
+ raise("Time cannot exceed six digits")
54
+ end
50
55
  end
51
- end
52
-
53
- # Return the next past or future Span for the time that this Repeater represents
54
- # pointer - Symbol representing which temporal direction to fetch the next day
55
- # must be either :past or :future
56
- def next(pointer)
57
- super
58
-
59
- half_day = 60 * 60 * 12
60
- full_day = 60 * 60 * 24
61
-
62
- first = false
63
-
64
- unless @current_time
65
- first = true
66
- midnight = Chronic.time_class.local(@now.year, @now.month, @now.day)
67
56
 
68
- yesterday_midnight = midnight - full_day
69
- tomorrow_midnight = midnight + full_day
70
-
71
- offset_fix = midnight.gmt_offset - tomorrow_midnight.gmt_offset
72
- tomorrow_midnight += offset_fix
73
-
74
- catch :done do
75
- if pointer == :future
76
- if @type.ambiguous?
77
- [midnight + @type + offset_fix, midnight + half_day + @type + offset_fix, tomorrow_midnight + @type].each do |t|
78
- (@current_time = t; throw :done) if t >= @now
79
- end
80
- else
81
- [midnight + @type + offset_fix, tomorrow_midnight + @type].each do |t|
82
- (@current_time = t; throw :done) if t >= @now
83
- end
84
- end
85
- else # pointer == :past
86
- if @type.ambiguous?
87
- [midnight + half_day + @type + offset_fix, midnight + @type + offset_fix, yesterday_midnight + @type + half_day].each do |t|
88
- (@current_time = t; throw :done) if t <= @now
57
+ # Return the next past or future Span for the time that this Repeater represents
58
+ # pointer - Symbol representing which temporal direction to fetch the next day
59
+ # must be either :past or :future
60
+ def next(pointer)
61
+ super
62
+
63
+ half_day = 60 * 60 * 12
64
+ full_day = 60 * 60 * 24
65
+
66
+ first = false
67
+
68
+ unless @current_time
69
+ first = true
70
+ midnight = Chronic.time_class.local(@now.year, @now.month, @now.day)
71
+
72
+ yesterday_midnight = midnight - full_day
73
+ tomorrow_midnight = midnight + full_day
74
+
75
+ offset_fix = midnight.gmt_offset - tomorrow_midnight.gmt_offset
76
+ tomorrow_midnight += offset_fix
77
+
78
+ catch :done do
79
+ if pointer == :future
80
+ if @type.ambiguous?
81
+ [midnight + @type.time + offset_fix, midnight + half_day + @type.time + offset_fix, tomorrow_midnight + @type.time].each do |t|
82
+ (@current_time = t; throw :done) if t >= @now
83
+ end
84
+ else
85
+ [midnight + @type.time + offset_fix, tomorrow_midnight + @type.time].each do |t|
86
+ (@current_time = t; throw :done) if t >= @now
87
+ end
89
88
  end
90
- else
91
- [midnight + @type + offset_fix, yesterday_midnight + @type].each do |t|
92
- (@current_time = t; throw :done) if t <= @now
89
+ else # pointer == :past
90
+ if @type.ambiguous?
91
+ [midnight + half_day + @type.time + offset_fix, midnight + @type.time + offset_fix, yesterday_midnight + @type.time + half_day].each do |t|
92
+ (@current_time = t; throw :done) if t <= @now
93
+ end
94
+ else
95
+ [midnight + @type.time + offset_fix, yesterday_midnight + @type.time].each do |t|
96
+ (@current_time = t; throw :done) if t <= @now
97
+ end
93
98
  end
94
99
  end
95
100
  end
101
+
102
+ @current_time || raise("Current time cannot be nil at this point")
96
103
  end
97
104
 
98
- @current_time || raise("Current time cannot be nil at this point")
99
- end
105
+ unless first
106
+ increment = @type.ambiguous? ? half_day : full_day
107
+ @current_time += pointer == :future ? increment : -increment
108
+ end
100
109
 
101
- unless first
102
- increment = @type.ambiguous? ? half_day : full_day
103
- @current_time += pointer == :future ? increment : -increment
110
+ Span.new(@current_time, @current_time + width)
104
111
  end
105
112
 
106
- Chronic::Span.new(@current_time, @current_time + width)
107
- end
108
-
109
- def this(context = :future)
110
- super
113
+ def this(context = :future)
114
+ super
111
115
 
112
- context = :future if context == :none
116
+ context = :future if context == :none
113
117
 
114
- self.next(context)
115
- end
118
+ self.next(context)
119
+ end
116
120
 
117
- def width
118
- 1
119
- end
121
+ def width
122
+ 1
123
+ end
120
124
 
121
- def to_s
122
- super << '-time-' << @type.to_s
125
+ def to_s
126
+ super << '-time-' << @type.to_s
127
+ end
123
128
  end
124
- end
129
+ end