module Chronic

Constants

VERSION

Attributes

debug[RW]

Public Class Methods

apply_endian_precedences(precedences) click to toggle source
# File lib/chronic/handlers.rb, line 108
def apply_endian_precedences(precedences)
  date_defs = @definitions[:date]

  # map the precedence array to indices on @definitions[:date]
  indices = precedences.map { |e|
    handler = instance_variable_get(endian_variable_name_for(e))
    date_defs.index(handler)
  }

  # swap the handlers if we discover they are at odds with the desired preferences
  swap(date_defs, indices.first, indices.last) if indices.first > indices.last
end
day_or_time(day_start, time_tokens, options) click to toggle source
# File lib/chronic/handlers.rb, line 128
def day_or_time(day_start, time_tokens, options)
  outer_span = Span.new(day_start, day_start + (24 * 60 * 60))
  
  if !time_tokens.empty?
    @now = outer_span.begin
    time = get_anchor(dealias_and_disambiguate_times(time_tokens, options), options)
    return time
  else
    return outer_span
  end
end
endian_variable_name_for(e) click to toggle source
# File lib/chronic/handlers.rb, line 121
def endian_variable_name_for(e)
  "@#{e.to_s}_endian_handler".to_sym
end
parse(text, specified_options = {}) click to toggle source

Parses a string containing a natural language date or time. If the parser can find a date or time, either a Time or Chronic::Span will be returned (depending on the value of :guess). If no date or time can be found, nil will be returned.

Options are:

:context

:past or :future (defaults to :future)

If your string represents a birthday, you can set :context to :past and if an ambiguous string is given, it will assume it is in the past. Specify :future or omit to set a future context.

:now

Time (defaults to Time.now)

By setting :now to a Time, all computations will be based off of that time instead of Time.now. If set to nil, Chronic will use Time.now.

:guess

true or false (defaults to true)

By default, the parser will guess a single point in time for the given date or time. If you’d rather have the entire time span returned, set :guess to false and a Chronic::Span will be returned.

:ambiguous_time_range

Integer or :none (defaults to 6 (6am-6pm))

If an Integer is given, ambiguous times (like 5:00) will be assumed to be within the range of that time in the AM to that time in the PM. For example, if you set it to 7, then the parser will look for the time between 7am and 7pm. In the case of 5:00, it would assume that means 5:00pm. If :none is given, no assumption will be made, and the first matching instance of that time will be used.

# File lib/chronic/chronic.rb, line 41
def parse(text, specified_options = {})
  @text = text
  
  # get options and set defaults if necessary
  default_options = {:context => :future,
                     :now => Chronic.time_class.now,
                     :guess => true,
                     :ambiguous_time_range => 6,
                     :endian_precedence => nil}
  options = default_options.merge specified_options
  
  # handle options that were set to nil
  options[:context] = :future unless options[:context]
  options[:now] = Chronic.time_class.now unless options[:context]
  options[:ambiguous_time_range] = 6 unless options[:ambiguous_time_range]
        
  # ensure the specified options are valid
  specified_options.keys.each do |key|
    default_options.keys.include?(key) || raise(InvalidArgumentException, "#{key} is not a valid option key.")
  end
  [:past, :future, :none].include?(options[:context]) || raise(InvalidArgumentException, "Invalid value ':#{options[:context]}' for :context specified. Valid values are :past and :future.")
  
  # store now for later =)
  @now = options[:now]
  
  # put the text into a normal format to ease scanning
  text = self.pre_normalize(text)
      
  # get base tokens for each word
  @tokens = self.base_tokenize(text)

  # scan the tokens with each token scanner
  [Repeater].each do |tokenizer|
    @tokens = tokenizer.scan(@tokens, options)
  end
  
  [Grabber, Pointer, Scalar, Ordinal, Separator, TimeZone].each do |tokenizer|
    @tokens = tokenizer.scan(@tokens)
  end
  
  # strip any non-tagged tokens
  @tokens = @tokens.select { |token| token.tagged? }
  
  if Chronic.debug
    puts "+---------------------------------------------------"
    puts "| " + @tokens.to_s
    puts "+---------------------------------------------------"
  end
  
  # do the heavy lifting
  begin
    span = self.tokens_to_span(@tokens, options)
  rescue
    raise
    return nil
  end
  
  # guess a time within a span if required
  if options[:guess]
    return self.guess(span)
  else
    return span
  end
end
swap(arr, a, b) click to toggle source

exchange two elements in an array

# File lib/chronic/handlers.rb, line 126
def swap(arr, a, b); arr[a], arr[b] = arr[b], arr[a]; end
time_class() click to toggle source
# File lib/chronic.rb, line 50
def time_class
  Thread.current[:chronic_time_class] ||= Time
end
time_class=(klass) click to toggle source
# File lib/chronic.rb, line 54
def time_class=(klass)
  Thread.current[:chronic_time_class] = klass
end