如何让工作时间安全?当它应该使用 Date 方法时确保它是 运行

How to make a Job time safe? Ensuring it is run when it's supposed to using Date methods

我们有 CreditCard 个相关的佣金任务,这些任务应该在每个月的 运行 日进行,以提醒我们的客户更新他们的付款方式(如果付款方式在上个月的某个时间点过期) .

class SomeJob < ApplicationJob

  def perform
    ::CreditCard.
      .where(expiration_date: Date.yesterday.all_month)
      .find_each do |credit_card|

      Email::CreditCard::SendExpiredReminderJob.perform_later(credit_card.id)
    end
  end
end

我担心我们目前拥有的这个特定工作可能 时区不安全,因为我们使用 Date.yesterday.all_month 获取上个月的日期范围(记住佣金任务是每个月的 1 日运行)。

例如,如果由于某种原因作业要 运行 午夜过后(2 日),它会错误地通知客户卡在本月到期,而它应该通知上个月过期的卡。

最安全的选择是从 Date 中减去超过 1 天,但我不确定这是最干净的方法(后来有人不明白为什么我们要减去 5、7天或其他)。

有没有更安全的方法?

Date.current.prev_month.all_month

.current 可能比 .today 更好,因为它会检查是否设置了时区,请参阅 answer

.prev_month.months_ago(1) 参见 https://apidock.com/rails/v3.2.13/Date/prev_month