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)
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