chronic 0.2.0 → 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 (58) hide show
  1. data/HISTORY.md +76 -0
  2. data/LICENSE +21 -0
  3. data/Manifest.txt +2 -0
  4. data/README.md +165 -0
  5. data/Rakefile +137 -32
  6. data/benchmark/benchmark.rb +13 -0
  7. data/chronic.gemspec +85 -0
  8. data/lib/chronic/chronic.rb +60 -50
  9. data/lib/chronic/grabber.rb +2 -2
  10. data/lib/chronic/handlers.rb +221 -111
  11. data/lib/{numerizer → chronic/numerizer}/numerizer.rb +17 -23
  12. data/lib/chronic/ordinal.rb +6 -6
  13. data/lib/chronic/pointer.rb +3 -3
  14. data/lib/chronic/repeater.rb +27 -12
  15. data/lib/chronic/repeaters/repeater_day.rb +23 -18
  16. data/lib/chronic/repeaters/repeater_day_name.rb +19 -14
  17. data/lib/chronic/repeaters/repeater_day_portion.rb +23 -22
  18. data/lib/chronic/repeaters/repeater_fortnight.rb +16 -11
  19. data/lib/chronic/repeaters/repeater_hour.rb +20 -15
  20. data/lib/chronic/repeaters/repeater_minute.rb +31 -16
  21. data/lib/chronic/repeaters/repeater_month.rb +33 -24
  22. data/lib/chronic/repeaters/repeater_month_name.rb +31 -26
  23. data/lib/chronic/repeaters/repeater_season.rb +136 -9
  24. data/lib/chronic/repeaters/repeater_season_name.rb +38 -17
  25. data/lib/chronic/repeaters/repeater_second.rb +15 -10
  26. data/lib/chronic/repeaters/repeater_time.rb +53 -43
  27. data/lib/chronic/repeaters/repeater_week.rb +16 -11
  28. data/lib/chronic/repeaters/repeater_weekday.rb +77 -0
  29. data/lib/chronic/repeaters/repeater_weekend.rb +14 -9
  30. data/lib/chronic/repeaters/repeater_year.rb +31 -25
  31. data/lib/chronic/scalar.rb +16 -14
  32. data/lib/chronic/separator.rb +25 -10
  33. data/lib/chronic/time_zone.rb +23 -0
  34. data/lib/chronic.rb +69 -14
  35. data/test/helper.rb +7 -0
  36. data/test/test_Chronic.rb +17 -18
  37. data/test/test_DaylightSavings.rb +118 -0
  38. data/test/test_Handler.rb +37 -38
  39. data/test/test_Numerizer.rb +8 -5
  40. data/test/test_RepeaterDayName.rb +15 -16
  41. data/test/test_RepeaterFortnight.rb +16 -17
  42. data/test/test_RepeaterHour.rb +18 -19
  43. data/test/test_RepeaterMinute.rb +34 -0
  44. data/test/test_RepeaterMonth.rb +16 -17
  45. data/test/test_RepeaterMonthName.rb +17 -18
  46. data/test/test_RepeaterTime.rb +20 -22
  47. data/test/test_RepeaterWeek.rb +16 -17
  48. data/test/test_RepeaterWeekday.rb +55 -0
  49. data/test/test_RepeaterWeekend.rb +21 -22
  50. data/test/test_RepeaterYear.rb +17 -18
  51. data/test/test_Span.rb +5 -6
  52. data/test/test_Time.rb +49 -0
  53. data/test/test_Token.rb +5 -6
  54. data/test/test_parsing.rb +338 -178
  55. metadata +78 -50
  56. data/History.txt +0 -38
  57. data/README.txt +0 -149
  58. data/test/suite.rb +0 -9
@@ -1,57 +1,66 @@
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
- @current_month_start = offset_by(Time.local(@now.year, @now.month), 1, pointer)
14
+ @current_month_start = offset_by(Time.construct(@now.year, @now.month), 1, pointer)
10
15
  else
11
- @current_month_start = offset_by(Time.local(@current_month_start.year, @current_month_start.month), 1, pointer)
16
+ @current_month_start = offset_by(Time.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
12
17
  end
13
-
14
- Chronic::Span.new(@current_month_start, Time.local(@current_month_start.year, @current_month_start.month + 1))
18
+
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
- month_start = Time.local(@now.year, @now.month, @now.day + 1)
23
- month_end = self.offset_by(Time.local(@now.year, @now.month), 1, :future)
27
+ month_start = Time.construct(@now.year, @now.month, @now.day + 1)
28
+ month_end = self.offset_by(Time.construct(@now.year, @now.month), 1, :future)
24
29
  when :past
25
- month_start = Time.local(@now.year, @now.month)
26
- month_end = Time.local(@now.year, @now.month, @now.day)
30
+ month_start = Time.construct(@now.year, @now.month)
31
+ month_end = Time.construct(@now.year, @now.month, @now.day)
27
32
  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)
33
+ month_start = Time.construct(@now.year, @now.month)
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
48
53
  new_year += 1
49
54
  new_month -= YEAR_MONTHS
50
55
  end
51
- Time.local(new_year, new_month, time.day, time.hour, time.min, time.sec)
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
- end
62
+
63
+ def to_s
64
+ super << '-month'
65
+ end
66
+ end
@@ -1,44 +1,49 @@
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
- @current_month_begin = Time.local(@now.year, target_month)
13
- else @now.month > target_month
14
- @current_month_begin = Time.local(@now.year + 1, target_month)
17
+ @current_month_begin = Time.construct(@now.year, target_month)
18
+ elsif @now.month > target_month
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
- @current_month_begin = Time.local(@now.year, target_month)
19
- else @now.month > target_month
20
- @current_month_begin = Time.local(@now.year + 1, target_month)
23
+ @current_month_begin = Time.construct(@now.year, target_month)
24
+ elsif @now.month > target_month
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
- @current_month_begin = Time.local(@now.year, target_month)
25
- else @now.month < target_month
26
- @current_month_begin = Time.local(@now.year - 1, target_month)
29
+ @current_month_begin = Time.construct(@now.year, target_month)
30
+ elsif @now.month < target_month
31
+ @current_month_begin = Time.construct(@now.year - 1, target_month)
27
32
  end
28
33
  end
29
34
  @current_month_begin || raise("Current month should be set by now")
30
35
  else
31
36
  case pointer
32
37
  when :future
33
- @current_month_begin = Time.local(@current_month_begin.year + 1, @current_month_begin.month)
38
+ @current_month_begin = Time.construct(@current_month_begin.year + 1, @current_month_begin.month)
34
39
  when :past
35
- @current_month_begin = Time.local(@current_month_begin.year - 1, @current_month_begin.month)
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
-
50
- Chronic::Span.new(@current_month_begin, Time.local(next_month_year, next_month_month))
54
+
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
- super << '-month-' << @type.to_s
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
@@ -1,23 +1,150 @@
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
14
+
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
24
+
25
+ class MiniDate
26
+ attr_accessor :month, :day
27
+
28
+ def initialize(month, day)
29
+ @month = month
30
+ @day = day
31
+ end
32
+
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)
36
+
37
+ i = md_start.month + 1
38
+ until i == md_end.month
39
+ return true if @month == i
40
+ i = (i+1) % 12
41
+ end
42
+
43
+ return false
44
+ end
45
+
46
+ def equals?(other)
47
+ @month == other.month and day == other.day
48
+ end
49
+ end
50
+
1
51
  class Chronic::RepeaterSeason < Chronic::Repeater #:nodoc:
52
+ YEAR_SEASONS = 4
2
53
  SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
3
-
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
63
+
4
64
  def next(pointer)
5
65
  super
6
-
7
- raise 'Not implemented'
66
+
67
+ direction = pointer == :future ? 1 : -1
68
+ next_season = Season.find_next_season(find_current_season(@now.to_minidate), direction)
69
+
70
+ find_next_season_span(direction, next_season)
8
71
  end
9
-
72
+
10
73
  def this(pointer = :future)
11
74
  super
12
-
13
- raise 'Not implemented'
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)
90
+ end
91
+
92
+ Chronic::Span.new(this_ssn_start, this_ssn_end)
14
93
  end
15
-
94
+
95
+ def offset(span, amount, pointer)
96
+ Chronic::Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
97
+ end
98
+
99
+ def offset_by(time, amount, pointer)
100
+ direction = pointer == :future ? 1 : -1
101
+ time + amount * direction * SEASON_SECONDS
102
+ end
103
+
16
104
  def width
17
105
  SEASON_SECONDS
18
106
  end
19
-
107
+
20
108
  def to_s
21
109
  super << '-season'
22
110
  end
23
- end
111
+
112
+ private
113
+
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)
118
+ end
119
+
120
+ @next_season_start += direction * num_seconds_til_start(next_season, direction)
121
+ @next_season_end += direction * num_seconds_til_end(next_season, direction)
122
+
123
+ Chronic::Span.new(@next_season_start, @next_season_end)
124
+ end
125
+
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)
129
+ 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
+
136
+ until (start + direction * seconds).to_minidate.equals?(goal)
137
+ seconds += Chronic::RepeaterDay::DAY_SECONDS
138
+ end
139
+
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
146
+
147
+ def num_seconds_til_end(season_symbol, direction)
148
+ num_seconds_til(SEASONS[season_symbol].end, direction)
149
+ end
150
+ end
@@ -1,24 +1,45 @@
1
+ require 'chronic/repeaters/repeater_season.rb'
2
+
1
3
  class Chronic::RepeaterSeasonName < Chronic::RepeaterSeason #:nodoc:
2
- @summer = ['jul 21', 'sep 22']
3
- @autumn = ['sep 23', 'dec 21']
4
- @winter = ['dec 22', 'mar 19']
5
- @spring = ['mar 20', 'jul 20']
6
-
4
+ SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
5
+ DAY_SECONDS = 86_400 # (24 * 60 * 60)
6
+
7
7
  def next(pointer)
8
- super
9
- raise 'Not implemented'
8
+ direction = pointer == :future ? 1 : -1
9
+ find_next_season_span(direction, @type)
10
10
  end
11
-
11
+
12
12
  def this(pointer = :future)
13
- super
14
- raise 'Not implemented'
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
31
+ end
32
+
33
+ Chronic::Span.new(this_ssn_start, this_ssn_end)
15
34
  end
16
-
17
- def width
18
- (91 * 24 * 60 * 60)
35
+
36
+ def offset(span, amount, pointer)
37
+ Chronic::Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
19
38
  end
20
-
21
- def to_s
22
- super << '-season-' << @type.to_s
39
+
40
+ def offset_by(time, amount, pointer)
41
+ direction = pointer == :future ? 1 : -1
42
+ time + amount * direction * Chronic::RepeaterYear::YEAR_SECONDS
23
43
  end
24
- end
44
+
45
+ end
@@ -1,36 +1,41 @@
1
1
  class Chronic::RepeaterSecond < Chronic::Repeater #:nodoc:
2
2
  SECOND_SECONDS = 1 # haha, awesome
3
-
3
+
4
+ def initialize(type)
5
+ super
6
+ @second_start = nil
7
+ end
8
+
4
9
  def next(pointer = :future)
5
10
  super
6
-
11
+
7
12
  direction = pointer == :future ? 1 : -1
8
-
13
+
9
14
  if !@second_start
10
15
  @second_start = @now + (direction * SECOND_SECONDS)
11
16
  else
12
17
  @second_start += SECOND_SECONDS * direction
13
18
  end
14
-
19
+
15
20
  Chronic::Span.new(@second_start, @second_start + SECOND_SECONDS)
16
21
  end
17
-
22
+
18
23
  def this(pointer = :future)
19
24
  super
20
-
25
+
21
26
  Chronic::Span.new(@now, @now + 1)
22
27
  end
23
-
28
+
24
29
  def offset(span, amount, pointer)
25
30
  direction = pointer == :future ? 1 : -1
26
31
  span + direction * amount * SECOND_SECONDS
27
32
  end
28
-
33
+
29
34
  def width
30
35
  SECOND_SECONDS
31
36
  end
32
-
37
+
33
38
  def to_s
34
39
  super << '-second'
35
40
  end
36
- end
41
+ end
@@ -1,114 +1,124 @@
1
1
  class Chronic::RepeaterTime < Chronic::Repeater #:nodoc:
2
2
  class Tick #:nodoc:
3
3
  attr_accessor :time
4
-
4
+
5
5
  def initialize(time, ambiguous = false)
6
6
  @time = time
7
7
  @ambiguous = ambiguous
8
8
  end
9
-
9
+
10
10
  def ambiguous?
11
11
  @ambiguous
12
12
  end
13
-
13
+
14
14
  def *(other)
15
15
  Tick.new(@time * other, @ambiguous)
16
16
  end
17
-
17
+
18
18
  def to_f
19
19
  @time.to_f
20
20
  end
21
-
21
+
22
22
  def to_s
23
23
  @time.to_s + (@ambiguous ? '?' : '')
24
24
  end
25
25
  end
26
-
26
+
27
27
  def initialize(time, options = {})
28
+ @current_time = nil
28
29
  t = time.gsub(/\:/, '')
29
- @type =
30
- if (1..2) === t.size
31
- Tick.new(t.to_i * 60 * 60, true)
32
- elsif t.size == 3
33
- Tick.new((t[0..0].to_i * 60 * 60) + (t[1..2].to_i * 60), true)
34
- elsif t.size == 4
35
- ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
36
- Tick.new(t[0..1].to_i * 60 * 60 + t[2..3].to_i * 60, ambiguous)
37
- elsif t.size == 5
38
- Tick.new(t[0..0].to_i * 60 * 60 + t[1..2].to_i * 60 + t[3..4].to_i, true)
39
- elsif t.size == 6
40
- ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
41
- Tick.new(t[0..1].to_i * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous)
42
- else
43
- raise("Time cannot exceed six digits")
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")
44
50
  end
45
51
  end
46
-
52
+
47
53
  # Return the next past or future Span for the time that this Repeater represents
48
54
  # pointer - Symbol representing which temporal direction to fetch the next day
49
55
  # must be either :past or :future
50
56
  def next(pointer)
51
57
  super
52
-
58
+
53
59
  half_day = 60 * 60 * 12
54
60
  full_day = 60 * 60 * 24
55
-
61
+
56
62
  first = false
57
-
63
+
58
64
  unless @current_time
59
65
  first = true
60
- midnight = Time.local(@now.year, @now.month, @now.day)
66
+ midnight = Chronic.time_class.local(@now.year, @now.month, @now.day)
67
+
61
68
  yesterday_midnight = midnight - full_day
62
69
  tomorrow_midnight = midnight + full_day
63
70
 
71
+ offset_fix = midnight.gmt_offset - tomorrow_midnight.gmt_offset
72
+ tomorrow_midnight += offset_fix
73
+
64
74
  catch :done do
65
75
  if pointer == :future
66
76
  if @type.ambiguous?
67
- [midnight + @type, midnight + half_day + @type, tomorrow_midnight + @type].each do |t|
68
- (@current_time = t; throw :done) if t > @now
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
69
79
  end
70
80
  else
71
- [midnight + @type, tomorrow_midnight + @type].each do |t|
72
- (@current_time = t; throw :done) if t > @now
81
+ [midnight + @type + offset_fix, tomorrow_midnight + @type].each do |t|
82
+ (@current_time = t; throw :done) if t >= @now
73
83
  end
74
84
  end
75
85
  else # pointer == :past
76
86
  if @type.ambiguous?
77
- [midnight + half_day + @type, midnight + @type, yesterday_midnight + @type * 2].each do |t|
78
- (@current_time = t; throw :done) if t < @now
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
79
89
  end
80
90
  else
81
- [midnight + @type, yesterday_midnight + @type].each do |t|
82
- (@current_time = t; throw :done) if t < @now
91
+ [midnight + @type + offset_fix, yesterday_midnight + @type].each do |t|
92
+ (@current_time = t; throw :done) if t <= @now
83
93
  end
84
94
  end
85
95
  end
86
96
  end
87
-
97
+
88
98
  @current_time || raise("Current time cannot be nil at this point")
89
99
  end
90
-
100
+
91
101
  unless first
92
102
  increment = @type.ambiguous? ? half_day : full_day
93
103
  @current_time += pointer == :future ? increment : -increment
94
104
  end
95
-
105
+
96
106
  Chronic::Span.new(@current_time, @current_time + width)
97
107
  end
98
-
108
+
99
109
  def this(context = :future)
100
110
  super
101
-
111
+
102
112
  context = :future if context == :none
103
-
113
+
104
114
  self.next(context)
105
115
  end
106
-
116
+
107
117
  def width
108
118
  1
109
119
  end
110
-
120
+
111
121
  def to_s
112
122
  super << '-time-' << @type.to_s
113
123
  end
114
- end
124
+ end