chronic-davispuh 0.10.2.v0.1da32066b3f46f2506b3471e39557497e34afa27

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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +3 -0
  5. data/HISTORY.md +243 -0
  6. data/LICENSE +21 -0
  7. data/README.md +185 -0
  8. data/Rakefile +68 -0
  9. data/chronic.gemspec +27 -0
  10. data/lib/chronic.rb +122 -0
  11. data/lib/chronic/arrow.rb +270 -0
  12. data/lib/chronic/date.rb +272 -0
  13. data/lib/chronic/definition.rb +208 -0
  14. data/lib/chronic/dictionary.rb +36 -0
  15. data/lib/chronic/handler.rb +44 -0
  16. data/lib/chronic/handlers/anchor.rb +65 -0
  17. data/lib/chronic/handlers/arrow.rb +84 -0
  18. data/lib/chronic/handlers/date.rb +270 -0
  19. data/lib/chronic/handlers/date_time.rb +72 -0
  20. data/lib/chronic/handlers/general.rb +130 -0
  21. data/lib/chronic/handlers/narrow.rb +54 -0
  22. data/lib/chronic/handlers/time.rb +167 -0
  23. data/lib/chronic/handlers/time_zone.rb +50 -0
  24. data/lib/chronic/objects/anchor_object.rb +263 -0
  25. data/lib/chronic/objects/arrow_object.rb +27 -0
  26. data/lib/chronic/objects/date_object.rb +164 -0
  27. data/lib/chronic/objects/date_time_object.rb +64 -0
  28. data/lib/chronic/objects/handler_object.rb +81 -0
  29. data/lib/chronic/objects/narrow_object.rb +85 -0
  30. data/lib/chronic/objects/time_object.rb +96 -0
  31. data/lib/chronic/objects/time_zone_object.rb +27 -0
  32. data/lib/chronic/parser.rb +154 -0
  33. data/lib/chronic/span.rb +32 -0
  34. data/lib/chronic/tag.rb +84 -0
  35. data/lib/chronic/tags/day_name.rb +34 -0
  36. data/lib/chronic/tags/day_portion.rb +33 -0
  37. data/lib/chronic/tags/day_special.rb +30 -0
  38. data/lib/chronic/tags/grabber.rb +29 -0
  39. data/lib/chronic/tags/keyword.rb +63 -0
  40. data/lib/chronic/tags/month_name.rb +39 -0
  41. data/lib/chronic/tags/ordinal.rb +52 -0
  42. data/lib/chronic/tags/pointer.rb +28 -0
  43. data/lib/chronic/tags/rational.rb +35 -0
  44. data/lib/chronic/tags/scalar.rb +101 -0
  45. data/lib/chronic/tags/season_name.rb +31 -0
  46. data/lib/chronic/tags/separator.rb +130 -0
  47. data/lib/chronic/tags/sign.rb +35 -0
  48. data/lib/chronic/tags/time_special.rb +34 -0
  49. data/lib/chronic/tags/time_zone.rb +56 -0
  50. data/lib/chronic/tags/unit.rb +174 -0
  51. data/lib/chronic/time.rb +141 -0
  52. data/lib/chronic/time_zone.rb +80 -0
  53. data/lib/chronic/token.rb +61 -0
  54. data/lib/chronic/token_group.rb +271 -0
  55. data/lib/chronic/tokenizer.rb +42 -0
  56. data/lib/chronic/version.rb +3 -0
  57. data/test/helper.rb +12 -0
  58. data/test/test_chronic.rb +190 -0
  59. data/test/test_daylight_savings.rb +98 -0
  60. data/test/test_handler.rb +113 -0
  61. data/test/test_parsing.rb +1520 -0
  62. data/test/test_span.rb +23 -0
  63. data/test/test_token.rb +31 -0
  64. metadata +218 -0
@@ -0,0 +1,141 @@
1
+ module Chronic
2
+ class Time
3
+ DAY_HOURS = 24
4
+ HOUR_MINUTES = 60
5
+ HOUR_SECONDS = 3600 # 60 * 60
6
+ MINUTE_SECONDS = 60
7
+ SECOND_SECONDS = 1 # haha, awesome
8
+ SUBSECOND_SECONDS = 0.001
9
+ SPECIAL = {
10
+ :am => (0... 12), # 0am to 12pm
11
+ :pm => (12...24), # 12am to 0am
12
+ :morning => (6... 12), # 6am to 12pm
13
+ :noon => (12.. 12), # 12pm
14
+ :afternoon => (13...17), # 1pm to 5pm
15
+ :evening => (17...20), # 5pm to 8pm
16
+ :night => (20...24), # 8pm to 0am
17
+ :midnight => (24.. 24) # 0am
18
+ }
19
+
20
+ # Checks if given number could be hour
21
+ def self.could_be_hour?(hour, width = nil, hours12 = false)
22
+ hour >= 0 && hour <= (hours12 ? 12 : 24) && (width.nil? || width > 0)
23
+ end
24
+
25
+ # Checks if given number could be minute
26
+ def self.could_be_minute?(minute, width = nil)
27
+ minute >= 0 && minute <= HOUR_MINUTES && (width.nil? || width <= 2)
28
+ end
29
+
30
+ # Checks if given number could be second
31
+ def self.could_be_second?(second, width = nil)
32
+ second >= 0 && second <= MINUTE_SECONDS && (width.nil? || width <= 2)
33
+ end
34
+
35
+ # Checks if given number could be subsecond
36
+ def self.could_be_subsecond?(subsecond, width = nil)
37
+ subsecond >= 0 && subsecond <= 99999999 && (width.nil? || width > 0)
38
+ end
39
+
40
+ def self.add_second(minute, second, amount = 1)
41
+ second += amount
42
+ if second >= MINUTE_SECONDS or second < 0
43
+ minute += second / MINUTE_SECONDS
44
+ second = second % MINUTE_SECONDS
45
+ end
46
+ [minute, second]
47
+ end
48
+
49
+ def self.add_minute(hour, minute, amount = 1)
50
+ minute += amount
51
+ if minute >= HOUR_MINUTES or minute < 0
52
+ hour += minute / HOUR_MINUTES
53
+ minute = minute % HOUR_MINUTES
54
+ end
55
+ [hour, minute]
56
+ end
57
+
58
+ def self.add_hour(day, hour, amount = 1)
59
+ hour += amount
60
+ if hour >= DAY_HOURS or hour < 0
61
+ day += hour / DAY_HOURS
62
+ hour = hour % DAY_HOURS
63
+ end
64
+ [day, hour]
65
+ end
66
+
67
+ def self.normalize(day, hour, minute, second)
68
+ minute, second = add_second(minute, second, 0)
69
+ hour, minute = add_minute(hour, minute, 0)
70
+ day, hour = add_hour(day, hour, 0)
71
+ [day, hour, minute, second]
72
+ end
73
+
74
+ def self.split(time)
75
+ if time.is_a?(::Time) or time.is_a?(::DateTime)
76
+ [time.hour, time.min, time.sec, time.to_time.utc_offset]
77
+ else
78
+ [0, 0, 0, nil]
79
+ end
80
+ end
81
+ end
82
+
83
+ module TimeStructure
84
+ include Comparable
85
+ attr_accessor :hour
86
+ attr_accessor :minute
87
+ attr_accessor :second
88
+ attr_reader :subsecond
89
+ attr_reader :subsecond_size
90
+ attr_reader :precision
91
+ def update(time)
92
+ @hour = time.hour
93
+ @minute = time.min
94
+ @second = time.sec
95
+ self
96
+ end
97
+
98
+ def is_equal?(time)
99
+ @hour == time.hour &&
100
+ @minute == time.min &&
101
+ @second == time.sec
102
+ end
103
+
104
+ def <=> (time)
105
+ to_f <=> time.hour * Time::HOUR_SECONDS + time.min * Time::MINUTE_SECONDS + time.sec
106
+ end
107
+
108
+ def to_a
109
+ [@hour, @minute, @second]
110
+ end
111
+
112
+ def to_f
113
+ @hour * Time::HOUR_SECONDS + @minute * Time::MINUTE_SECONDS + @second
114
+ end
115
+
116
+ def get_end
117
+ [@hour, @minute, @second]
118
+ end
119
+
120
+ def to_span(date, timezone = nil)
121
+ span_start = Chronic.construct(date.year, date.month, date.day, @hour, @minute, @second, timezone)
122
+ end_hour, end_minute, end_second = get_end
123
+ span_end = Chronic.construct(date.year, date.month, date.day, end_hour, end_minute, end_second, timezone)
124
+ Span.new(span_start, span_end, true)
125
+ end
126
+ end
127
+
128
+ class TimeInfo
129
+ include TimeStructure
130
+ def initialize(now = nil)
131
+ if now
132
+ update(now)
133
+ else
134
+ @hour = 0
135
+ @minute = 0
136
+ @second = 0
137
+ end
138
+ end
139
+ end
140
+
141
+ end
@@ -0,0 +1,80 @@
1
+ module Chronic
2
+ class TimeZone
3
+
4
+ # normalize offset in seconds to offset as string +mm:ss or -mm:ss
5
+ def self.normalize_offset(offset = nil)
6
+ return offset if offset.is_a?(String)
7
+ offset = Chronic.time_class.now.to_time.utc_offset unless offset # get current system's UTC offset if offset is nil
8
+ sign = '+'
9
+ sign = '-' if offset < 0
10
+ hours = (offset.abs / Time::HOUR_SECONDS).to_i.to_s.rjust(2,'0')
11
+ minutes = (offset.abs % Time::HOUR_SECONDS).to_s.rjust(2,'0')
12
+ sign + hours + minutes
13
+ end
14
+
15
+ def self.abbreviation_offests(abbr, date = nil)
16
+ TimezoneParser::Abbreviation.getOffsets(abbr, date, date).first
17
+ end
18
+
19
+ def self.name_offsets(name, date = nil)
20
+ TimezoneParser::Timezone.getOffsets(name, date, date).first
21
+ end
22
+
23
+ def self.zone_offsets(zone)
24
+ TZInfo::Timezone.get(@zone).current_period.utc_offset
25
+ end
26
+
27
+ def self.is_valid_abbr?(abbr)
28
+ TimezoneParser::Abbreviation.isValid?(abbr)
29
+ end
30
+
31
+ def self.is_valid_name?(name)
32
+ TimezoneParser::Timezone.isValid?(name)
33
+ end
34
+
35
+ def self.is_valid_zone?(name)
36
+ false # TODO
37
+ end
38
+
39
+ def self.to_offset(hour, minute, sign = 1)
40
+ offset = hour * Time::HOUR_SECONDS + minute * Time::MINUTE_SECONDS
41
+ offset *= sign
42
+ offset
43
+ end
44
+
45
+ end
46
+
47
+ module TimeZoneStructure
48
+ attr_reader :offset
49
+ attr_reader :sign
50
+ attr_reader :tzhour
51
+ attr_reader :tzminute
52
+ attr_reader :name
53
+ attr_reader :abbr
54
+ attr_reader :zone
55
+
56
+ def to_offset(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
57
+ date = DateTime.new(year, month, day, hour, minute, second)
58
+ if @abbr
59
+ TimeZone::abbreviation_offests(@abbr, date)
60
+ elsif @name
61
+ TimeZone::name_offsets(@name, date)
62
+ elsif @zone
63
+ TimeZone::zone_offsets(@zone)
64
+ elsif @tzhour
65
+ sign = 1
66
+ sign = -1 if @sign and @sign.type == :minus
67
+ TimeZone::to_offset(@tzhour, @tzminute, sign)
68
+ else
69
+ @offset
70
+ end
71
+ end
72
+
73
+ def to_s
74
+ sign = @sign ? @sign.type.inspect : 'nil'
75
+ "sign #{sign}, tzhour #{@tzhour.inspect}, tzminute #{@tzminute.inspect}, offset #{@offset.inspect}, name #{@name.inspect}, abbr #{@abbr.inspect}, zone #{@zone.inspect}"
76
+ end
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,61 @@
1
+ module Chronic
2
+ class Token
3
+
4
+ attr_accessor :word
5
+ attr_accessor :tags
6
+
7
+ attr_reader :text
8
+ attr_reader :position
9
+
10
+ def initialize(word, text = nil, position = 0)
11
+ @word = word
12
+ @tags = []
13
+ @text = text
14
+ @position = position
15
+ end
16
+
17
+ def ==(token)
18
+ token.word == @word.downcase
19
+ end
20
+
21
+ # Tag this token with the specified tag.
22
+ #
23
+ # new_tag - The new Tag object.
24
+ #
25
+ # Returns nothing.
26
+ def tag(new_tag)
27
+ @tags << new_tag if new_tag
28
+ end
29
+
30
+ # Remove all tags of the given class.
31
+ #
32
+ # tag_class - The tag Class to remove.
33
+ #
34
+ # Returns nothing.
35
+ def untag(tag_class)
36
+ @tags.delete_if { |m| m.kind_of? tag_class }
37
+ end
38
+
39
+ # Returns true if this token has any tags.
40
+ def tagged?
41
+ @tags.size > 0
42
+ end
43
+
44
+ # tag_class - The tag Class to search for.
45
+ #
46
+ # Returns The first Tag that matches the given class.
47
+ def get_tag(tag_class)
48
+ @tags.find { |m| m.kind_of? tag_class }
49
+ end
50
+
51
+ # Print this Token in a pretty way
52
+ def to_s
53
+ @word + '(' + @tags.join(', ') + ') '
54
+ end
55
+
56
+ def inspect
57
+ to_s
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,271 @@
1
+ require 'chronic/objects/handler_object'
2
+ require 'chronic/objects/anchor_object'
3
+ require 'chronic/objects/arrow_object'
4
+ require 'chronic/objects/narrow_object'
5
+ require 'chronic/objects/date_object'
6
+ require 'chronic/objects/date_time_object'
7
+ require 'chronic/objects/time_object'
8
+ require 'chronic/objects/time_zone_object'
9
+
10
+ module Chronic
11
+ class TokenGroup
12
+
13
+ attr_reader :arrows
14
+ attr_reader :narrows
15
+ attr_reader :dates
16
+ attr_reader :times
17
+ attr_reader :timezones
18
+ def initialize(tokens, definitions, local_date, options)
19
+ @anchors = []
20
+ @arrows = []
21
+ @narrows = []
22
+ @datetime = []
23
+ @dates = []
24
+ @times = []
25
+ @timezones = []
26
+ @local_date = local_date
27
+ @options = options
28
+
29
+ date_definitions = definitions[:date] + definitions[:endian] + definitions[:short_date]
30
+
31
+ tokens.each_index do |i|
32
+
33
+ if @anchors.last.nil? or i > @anchors.last.end
34
+ anchor = AnchorObject.new(tokens, i, definitions[:anchor], local_date, options)
35
+ @anchors << anchor if anchor.width > 0
36
+ end
37
+ @anchors.sort_by! { |a| a.width }.reverse!
38
+
39
+ if @arrows.last.nil? or i > @arrows.last.end
40
+ arrow = ArrowObject.new(tokens, i, definitions[:arrow], local_date, options)
41
+ @arrows << arrow if arrow.width > 0
42
+ end
43
+
44
+ if @narrows.last.nil? or i > @narrows.last.end
45
+ narrow = NarrowObject.new(tokens, i, definitions[:narrow], local_date, options)
46
+ @narrows << narrow if narrow.width > 0
47
+ end
48
+
49
+ if @datetime.last.nil? or i > @datetime.last.end
50
+ date = DateTimeObject.new(tokens, i, definitions[:date_time], local_date, options)
51
+ @datetime << date if date.width > 0
52
+ end
53
+
54
+ if @dates.last.nil? or i > @dates.last.end
55
+ date = DateObject.new(tokens, i, date_definitions, local_date, options)
56
+ @dates << date if date.width > 0
57
+ end
58
+
59
+ if @times.last.nil? or i > @times.last.end or not tokens[@times.last.begin].get_tag(ScalarWide).nil?
60
+ time = TimeObject.new(tokens, i, definitions[:time], local_date, options)
61
+ @times << time if time.width > 0
62
+ end
63
+ @times.sort_by! { |a| a.width }.reverse!
64
+
65
+ if @timezones.last.nil? or i > @timezones.last.end
66
+ timezone = TimeZoneObject.new(tokens, i, definitions[:timezone], local_date, options)
67
+ @timezones << timezone if timezone.width > 0
68
+ end
69
+
70
+ end
71
+ end
72
+
73
+ def get_anchor
74
+ @anchors.find do |anchor|
75
+ anchor.is_valid?
76
+ end
77
+ end
78
+
79
+ def get_arrow(anchor = nil)
80
+ arrows = @arrows.select do |arrow|
81
+ (anchor.nil? or (not arrow.overlap?(anchor.range) or arrow.width > anchor.width)) and
82
+ arrow.is_valid?
83
+ end
84
+ Arrow.new(arrows, @options) unless arrows.empty?
85
+ end
86
+
87
+ def get_narrow(anchor = nil, arrow = nil)
88
+ @narrows.find do |narrow|
89
+ (anchor.nil? or (not narrow.overlap?(anchor.range) or narrow.width >= anchor.width)) and
90
+ (arrow.nil? or not narrow.overlap?(arrow.range) or narrow.width >= arrow.width) and
91
+ narrow.is_valid?
92
+ end
93
+ end
94
+
95
+ def get_datetime(anchor = nil, arrow = nil, narrow = nil)
96
+ @datetime.find do |datetime|
97
+ (anchor.nil? or not datetime.overlap?(anchor.range)) and
98
+ (arrow.nil? or not datetime.overlap?(arrow.range)) and
99
+ (narrow.nil? or not datetime.overlap?(narrow.range)) and
100
+ datetime.is_valid?
101
+ end
102
+ end
103
+
104
+ def get_date(anchor = nil, arrow = nil, narrow = nil, datetime = nil)
105
+ @dates.find do |date|
106
+ (anchor.nil? or not date.overlap?(anchor.range)) and
107
+ (arrow.nil? or (not date.overlap?(arrow.range) or date.width > arrow.width or narrow)) and
108
+ (narrow.nil? or not date.overlap?(narrow.range)) and
109
+ (datetime.nil? or not date.overlap?(datetime.range)) and
110
+ date.is_valid?
111
+ end
112
+ end
113
+
114
+ def get_next_date(anchor = nil, arrow, narrow, datetime, date, time, timezone)
115
+ @dates.find do |nextdate|
116
+ not nextdate.overlap?(date.range) and
117
+ (anchor.nil? or not nextdate.overlap?(anchor.range)) and
118
+ (arrow.nil? or not nextdate.overlap?(arrow.range)) and
119
+ (narrow.nil? or not nextdate.overlap?(narrow.range)) and
120
+ (datetime.nil? or not nextdate.overlap?(datetime.range)) and
121
+ (time.nil? or not nextdate.overlap?(time.range)) and
122
+ (timezone.nil? or not nextdate.overlap?(timezone.range)) and
123
+ nextdate.is_valid? and not nextdate.year.nil?
124
+ end
125
+ end
126
+
127
+ def get_time(anchor = nil, arrow = nil, narrow = nil, datetime = nil, date = nil)
128
+ @times.find do |time|
129
+ (anchor.nil? or (not time.overlap?(anchor.range) or time.width > anchor.width)) and
130
+ (arrow.nil? or (not time.overlap?(arrow.range) or time.end >= arrow.end)) and
131
+ (narrow.nil? or not time.overlap?(narrow.range)) and
132
+ (datetime.nil? or not time.overlap?(datetime.range)) and
133
+ (date.nil? or (not time.overlap?(date.range) or time.width >= date.width )) and
134
+ time.is_valid?
135
+ end
136
+ end
137
+
138
+ def get_timezone(anchor = nil, arrow = nil, narrow = nil, datetime = nil, date = nil, time = nil)
139
+ @timezones.find do |timezone|
140
+ (anchor.nil? or not timezone.overlap?(anchor.range)) and
141
+ (arrow.nil? or not timezone.overlap?(arrow.range)) and
142
+ (narrow.nil? or not timezone.overlap?(narrow.range)) and
143
+ (datetime.nil? or not timezone.overlap?(datetime.range)) and
144
+ (date.nil? or not timezone.overlap?(date.range)) and
145
+ (time.nil? or not timezone.overlap?(time.range)) and
146
+ timezone.is_valid?
147
+ end
148
+ end
149
+
150
+ def update_date(anchor, arrow, narrow, datetime, date, time, timezone)
151
+ return if not date or date.year.nil?
152
+ next_date = get_next_date(anchor, arrow, narrow, datetime, date, time, timezone)
153
+ date.year = next_date.year if next_date
154
+ end
155
+
156
+ def refresh(anchor, arrow, narrow, datetime, date, time, timezone)
157
+ anchor = nil if anchor and (
158
+ (arrow and anchor.overlap?(arrow.range)) or
159
+ (datetime and anchor.overlap?(datetime.range)) or
160
+ (date and anchor.overlap?(date.range)) or
161
+ (time and anchor.overlap?(time.range)) or
162
+ (timezone and anchor.overlap?(timezone.range))
163
+ )
164
+ arrow = nil if arrow and (
165
+ (narrow and arrow.overlap?(narrow.range)) or
166
+ (datetime and arrow.overlap?(datetime.range)) or
167
+ (date and arrow.overlap?(date.range)) or
168
+ (time and arrow.overlap?(time.range)) or
169
+ (timezone and arrow.overlap?(timezone.range))
170
+ )
171
+ narrow = nil if narrow and (
172
+ (datetime and narrow.overlap?(datetime.range)) or
173
+ (date and narrow.overlap?(date.range)) or
174
+ (time and narrow.overlap?(time.range)) or
175
+ (timezone and narrow.overlap?(timezone.range))
176
+ )
177
+
178
+ if anchor and narrow and anchor.overlap?(narrow.range)
179
+ if date or narrow.width > anchor.width
180
+ anchor = nil
181
+ else
182
+ narrow = nil
183
+ end
184
+ end
185
+
186
+ if date and time and date.overlap?(time.range)
187
+ if time.width > date.width or anchor
188
+ date = nil
189
+ else
190
+ time = nil
191
+ end
192
+ end
193
+ [anchor, arrow, narrow, datetime, date, time, timezone]
194
+ end
195
+
196
+ def get_all
197
+ anchor = get_anchor
198
+ arrow = get_arrow(anchor)
199
+ narrow = get_narrow(anchor, arrow)
200
+ datetime = get_datetime(anchor, arrow, narrow)
201
+ date = get_date(anchor, arrow, narrow, datetime)
202
+ time = get_time(anchor, arrow, narrow, datetime, date)
203
+ timezone = get_timezone(anchor, arrow, narrow, datetime, date, time)
204
+ update_date(anchor, arrow, narrow, datetime, date, time, timezone)
205
+ refresh(anchor, arrow, narrow, datetime, date, time, timezone)
206
+ end
207
+
208
+ def get_sign
209
+ (@options[:context] == :past) ? -1 : ((@options[:context] == :future) ? 1 : 0)
210
+ end
211
+
212
+ def to_span
213
+ span = nil
214
+ objects = get_all
215
+ anchor, arrow, narrow, datetime, date, time, timezone = objects
216
+ if datetime
217
+ puts "\nUse " + datetime.class.to_s if Chronic.debug
218
+ span = datetime.to_span
219
+ elsif anchor or arrow or narrow or datetime or date or time
220
+ puts "\nUse " + objects.reject(&:nil?).sort_by { |o| o.begin }.map(&:class).join(' + ') if Chronic.debug
221
+
222
+ if arrow
223
+ time = TimeInfo.new(@local_date) if not time
224
+ arrow_date = date
225
+ arrow_date = DateInfo.new(@local_date) unless arrow_date
226
+ span = arrow_date.to_span(time, timezone)
227
+ span = arrow.to_span(span, timezone)
228
+ end
229
+
230
+ if anchor
231
+ time = TimeInfo.new(@local_date) if not time
232
+ span = anchor.to_span(span, time, timezone)
233
+ if date
234
+ sbegin = span.begin
235
+ date.local_date = sbegin
236
+ date.force_normalize!
237
+ span = date.to_span(nil, timezone)
238
+ sign = get_sign
239
+ if not sign.zero? and date.wday.nil? and (span.begin - @local_date) * sign < 0
240
+ year, month, day = Date::split(sbegin)
241
+ date.local_date = ::Time::mktime(year + sign, month, day)
242
+ date.force_normalize!
243
+ span = date.to_span(nil, timezone)
244
+ end
245
+ end
246
+ end
247
+
248
+ if not arrow and not anchor and time
249
+ sign = get_sign
250
+ time_compare = sign.zero? ? false : ((sign == -1) ? (time > @local_date) : (time < @local_date))
251
+ date = DateInfo.new(@local_date) unless date
252
+ date.add_day(sign) if not date.is_a?(DateObject) and date.is_equal?(@local_date) and time_compare
253
+ span = time.to_span(date, timezone)
254
+ end
255
+
256
+ span = date.to_span(nil, timezone) if span.nil? and date
257
+
258
+ span = narrow.to_span(span, timezone) if narrow
259
+
260
+ end
261
+
262
+ if Chronic.debug
263
+ puts "\n-- Span" + span.to_s if span
264
+ puts '-none' unless span
265
+ end
266
+
267
+ span
268
+ end
269
+
270
+ end
271
+ end