【问题标题】:How to calculate next monthly day anniversary如何计算下个月的周年纪念日
【发布时间】:2018-01-22 14:47:28
【问题描述】:

如果我有一个流程,我想在一个月中的特定日期运行。每个月计算周年纪念日的最佳方法是什么? 例如,如果我想在每个月的 30 日向某人收费。

我知道我可以安装一些 GEM,但这似乎有点矫枉过正。此外,Date#>> 方法仅适用于计算下个月。那之后的一个月呢?

我在下面发布了我的代码,这是我想出的最佳解决方案。

【问题讨论】:

  • 考虑使用Date#>>
  • @CarySwoveland Date#>> 方法仅适用于计算下个月。那之后的一个月呢?
  • 如果 d 是您的 Date 对象,则 d >> 3 是之后一个月内同一天的日期 3 (除了有时 dom is > 28 时)。您还可以从一个 Date 对象跳转到下一个对象:d = start_date; 12.times { <do something for value of d>; d = d >> 1 }
  • "计算每个月的周年纪念日" – 你的意思是什么?您想每月运行一次该方法还是希望该方法产生所有即将到来的日期?此外,您在该日期之前/之后/之后的输入和预期输出是什么?

标签: ruby-on-rails ruby


【解决方案1】:

根据您自己的回答,这也可以:

def next_month_anniversary(mday, today = Date.today)
  d = today.next_month
  if Date.valid_date?(d.year, d.month, mday)
    Date.new(d.year, d.month, mday)
  else
    Date.new(d.year, d.month, -1)
  end
end

或者更简洁一点:

def next_month_anniversary(mday, today = Date.today)
  d = today.next_month
  mday = -1 unless Date.valid_date?(d.year, d.month, mday)
  Date.new(d.year, d.month, mday)
end

例子:

next_month_anniversary(30, Date.new(2018, 1, 31))
#=> #<Date: 2018-02-28 ...>

【讨论】:

    【解决方案2】:

    你应该使用提前

    https://apidock.com/rails/DateTime/advance

    Date.current.advance(months: 2)   
    

    根据评论进行编辑:在您的初始日期提前致电了解未来发生的任何情况

     my_date = Date.new(2018, 1, 30) #example but mean to be the date you set up as to be recurrent
     my_date.advance(months:1) #Wed, 28 Feb 2018 
    

    【讨论】:

    • OP 想要明确地设置月份中的哪一天,例如 30
    • 他说“例如”。要计算下个月和未来的无硬编码 1,提前是最直接/最简单的方法。
    • 当然可以,但您的回答并未涉及 “在一个月中的特定日期” 部分。
    • 关于您的编辑:如果初始日期是 Date.new(2018, 2, 28),您怎么能提前到 3 月 30 日?
    • 为什么?为什么会在 28 日运行一个月,在 30 日运行下一个?你错过了重复计划的要点。您将如何使用您的方法获得提前 x 天 n 个月的日期?循环通过你的方法?提前所有都在一行电话中完成
    【解决方案3】:

    这是我能想到的最佳解决方案。在这种情况下,现在是 1 月 31 日,我想在每个月的 30 日返回一个周年纪念日。

    > MyClass.next_month_anniversary(30, '2018-01-30'.to_date)
     => Wed, 28 Feb 2018    
    

    代码如下:

      def next_month_anniversary(day_of_month, today = Date.today)
        month = (today >> 1).month
        year =  (today >> 1).year
        days_in_month = Time.days_in_month(month.to_i, year.to_i)
        if days_in_month < day_of_month
          day = days_in_month
        else
          day = day_of_month
        end
        Date.new(year.to_i, month.to_i, day.to_i)
      end
    

    【讨论】:

    • “现在是 1 月 31 日” – 差一分,你正在通过'2018-01-30'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多