class RuboCop::Cop::Rails::Date

date.to_time_in_current_zone
# reports offense only when style is ‘strict’
date.to_time
Date.today
# always reports offense
Date.yesterday
Date.current
# acceptable
Time.zone.today - 1.day
Time.zone.today
# no offense
@example
and only ‘to_time’ is reported as warning.
When EnforcedStyle is ‘flexible’ then only ‘Date.today’ is prohibited
and ‘to_time_in_current_zone’ is reported as warning.
are prohibited and the usage of both ‘to_time’
then the Date methods (today, current, yesterday, tomorrow)
Two styles are supported for this cop. When EnforcedStyle is ‘strict’
because it doesn’t know about Rails time zone too.
The cop also reports warnings when you are using ‘to_time’ method,
Rails time zone. You must use Time.zone.today instead.
Using Date.today is dangerous, because it doesn’t know anything about
such as Date.today, Date.current etc.
This cop checks for the correct use of Date methods,

def bad_days

def bad_days
  BAD_DAYS - good_days
end

def bad_methods

def bad_methods
  style == :strict ? [:to_time, :to_time_in_current_zone] : [:to_time]
end

def check_date_node(node)

def check_date_node(node)
  chain = extract_method_chain(node)
  return if (chain & bad_days).empty?
  method_name = (chain & bad_days).join('.')
  add_offense(node, :selector,
              format(MSG,
                     "Date.#{method_name}",
                     "Time.zone.#{method_name}")
             )
end

def extract_method(node)

def extract_method(node)
  _receiver, method_name, *_args = *node
  method_name
end

def extract_method_chain(node)

def extract_method_chain(node)
  chain = []
  while !node.nil? && node.send_type?
    chain << extract_method(node)
    node = node.parent
  end
  chain
end

def good_days

def good_days
  style == :strict ? [] : [:current, :yesterday, :tomorrow]
end

def method_send?(node)

and receiver is the given node
checks that parent node of send_type
def method_send?(node)
  return false unless node.parent && node.parent.send_type?
  receiver, _method_name, *_args = *node.parent
  receiver == node
end

def on_const(node)

def on_const(node)
  mod, klass = *node.children
  # we should only check core Date class (`Date` or `::Date`)
  return unless (mod.nil? || mod.cbase_type?) && method_send?(node)
  check_date_node(node.parent) if klass == :Date
end

def on_send(node)

def on_send(node)
  receiver, method_name, *args = *node
  return unless receiver && bad_methods.include?(method_name)
  return if method_name == :to_time && args.length == 1
  add_offense(node, :selector,
              format(MSG_SEND,
                     method_name
                    )
             )
end