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
# flexible
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 either.
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 ? %i[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_chain(node)

def extract_method_chain(node)
  [node, *node.each_ancestor(:send)].map(&:method_name)
end

def good_days

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

def good_methods

def good_methods
  style == :strict ? [] : TimeZone::ACCEPTED_METHODS
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?
  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)
  return unless node.receiver && bad_methods.include?(node.method_name)
  return if safe_chain?(node) || safe_to_time?(node)
  add_offense(node, :selector, format(MSG_SEND, node.method_name))
end

def safe_chain?(node)

def safe_chain?(node)
  chain = extract_method_chain(node)
  (chain & bad_methods).empty? || !(chain & good_methods).empty?
end

def safe_to_time?(node)

def safe_to_time?(node)
  return unless node.method?(:to_time)
  if node.receiver.str_type?
    zone_regexp = /[+-][\d:]+\z/
    node.receiver.str_content.match(zone_regexp)
  else
    node.arguments.one?
  end
end