Method: Doing::ChronifyString#split_date_range

Defined in:
lib/doing/chronify/string.rb

#split_date_rangeArray<DateTime>

Splits a range string and returns an array of DateTime objects as [start, end]. If only one date is given, end time is nil.

Examples:

Process a natural language date range

"mon 3pm to mon 5pm".split_date_range

Returns:

  • (Array<DateTime>)

    Start and end dates as array



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/doing/chronify/string.rb', line 178

def split_date_range
  time_rx = /^(\d{1,2}(:\d{1,2})?( *(am|pm))?|midnight|noon)$/
  range_rx = / (to|through|thru|(?:un)?til|-+) /

  date_string = dup

  if date_string.is_range?
    # Do we want to differentiate between "to" and "through"?
    # inclusive = date_string =~ / (through|thru|-+) / ? true : false
    inclusive = true

    dates = date_string.split(range_rx)

    if dates[0].strip =~ time_rx && dates[-1].strip =~ time_rx
      start = dates[0].strip
      finish = dates[-1].strip
    else
      start = dates[0].chronify(guess: :begin, future: false)
      finish = dates[-1].chronify(guess: inclusive ? :end : :begin, future: true)
    end

    raise Errors::InvalidTimeExpression, "Unrecognized date string (#{dates[0]})" if start.nil?

    raise Errors::InvalidTimeExpression, "Unrecognized date string (#{dates[-1]})" if finish.nil?

  else
    if date_string.strip =~ time_rx
      start = date_string.strip
      finish = '11:59pm'
    else
      start = date_string.strip.chronify(guess: :begin, future: false)
      finish = start + (24 * 60 * 60)
    end
    raise Errors::InvalidTimeExpression, 'Unrecognized date string' unless start

  end


  if start.is_a? String
    Doing.logger.debug('Parser:',
                       "--from string interpreted as time span, from #{start || '12am'} to #{finish || '11:59pm'}")
  else
    Doing.logger.debug('Parser:',
                       "date range interpreted as #{start.strftime('%F %R')} -- #{finish ? finish.strftime('%F %R') : 'now'}")
  end
  [start, finish]
end