class RuboCop::Cop::Rails::Date

date.to_time
# bad
@example AllowToTime: false
date.to_time
# good
@example AllowToTime: true (default)
Time.zone.today - 1.day
Time.zone.today
# good
Date.today
Date.yesterday
Date.current
# bad
@example EnforcedStyle: strict
date.in_time_zone
Date.yesterday
Date.current
Time.zone.today - 1.day
Time.zone.today
# good
Date.today
# bad
@example EnforcedStyle: flexible (default)
This cop’s autocorrection is unsafe because it may change handling time.
@safety
`AllowToTime` is ‘true` by default to prevent false positive on `DateTime` object.
And you can set a warning for `to_time` with `AllowToTime: false`.
When `EnforcedStyle` is `flexible` then only `Date.today` is prohibited.
and `to_time_in_current_zone` are reported as warning.
are prohibited and the usage of both `to_time`
then the Date methods `today`, `current`, `yesterday`, and `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.
Checks for the correct use of Date methods,

def allow_to_time?

def allow_to_time?
  cop_config.fetch('AllowToTime', true)
end

def bad_days

def bad_days
  BAD_DAYS - good_days
end

def bad_methods

def bad_methods
  %i[to_time to_time_in_current_zone]
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('.')
  day = method_name
  day = 'today' if method_name == 'current'
  message = format(MSG, method_called: method_name, day: day)
  add_offense(node.loc.selector, message: message) do |corrector|
    corrector.replace(node.receiver.loc.name, 'Time.zone')
  end
end

def check_deprecated_methods(node)

def check_deprecated_methods(node)
  DEPRECATED_METHODS.each do |method|
    next unless node.method?(method[:deprecated].to_sym)
    message = format(DEPRECATED_MSG, deprecated: method[:deprecated], relevant: method[:relevant])
    add_offense(node.loc.selector, message: message) do |corrector|
      corrector.replace(node.loc.selector, method[:relevant].to_s)
    end
  end
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&.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 allow_to_time? && node.method?(:to_time)
  return if safe_chain?(node) || safe_to_time?(node)
  check_deprecated_methods(node)
  add_offense(node.loc.selector, message: format(MSG_SEND, method: 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 false unless node.method?(:to_time)
  if node.receiver.str_type?
    zone_regexp = /([+-][\d:]+|\dZ)\z/
    node.receiver.str_content.match(zone_regexp)
  else
    node.arguments.one?
  end
end