【问题标题】:Given a date, how can I efficiently calculate the next date in a given sequence (weekly, monthly, annually)?给定一个日期,我如何有效地计算给定顺序(每周、每月、每年)中的下一个日期?
【发布时间】:2018-08-01 23:34:38
【问题描述】:

在我的应用程序中,我有多种日期序列,例如每周、每月和每年。给定过去的任意日期,我需要计算序列中的下一个 future 日期。

目前我正在使用次优循环。这是一个简化的示例(在 Ruby/Rails 中):

def calculate_next_date(from_date)
  next_date = from_date
  while next_date < Date.today
    next_date += 1.week # (or 1.month)
  end
  next_date
end

而不是执行一个循环(虽然简单,但效率低下,尤其是在给定一个遥远过去的日期时)我想通过计算日期之间的周数(或月数、年数)来执行此操作两个日期,计算余数并使用这些值生成下一个日期。

这是正确的方法,还是我错过了一种特别聪明的“Ruby”方法来解决这个问题?还是为了简单起见,我应该坚持使用循环?

【问题讨论】:

  • 你自称是ollydbg的olly吗?

标签: ruby-on-rails ruby algorithm date


【解决方案1】:

因为您将此问题标记为ruby-on-rails,所以我想您正在使用Rails。 ActiveSupport 引入了calculation 模块,它提供了一个有用的#advance 方法。

date = Date.today
date.advance(:weeks => 1)
date.advance(:days => 7)
# => next week

【讨论】:

  • 我认为您的意思是date.advance(:weeks =&gt; 1),因为该代码不起作用。
  • change 不支持 :weeks 选项。我更新了代码,谢谢。
【解决方案2】:

我过去曾为此使用过recurrence gem。列出了here 列出的重复事件模型的其他一些宝石。

【讨论】:

    【解决方案3】:

    如果您使用Time 对象,您可以使用Time.to_a 将时间分解为一个数组(字段表示小时、日、月等),调整适当的字段,然后将数组传回到Time.localTime.utc 构建一个新的Time 对象。

    如果您使用的是 Date 类,date +/- n 会给您一个日期后/早 n 天,date &gt;&gt;/&lt;&lt; n 会给您一个日期后/早 n 个月。

    您可以使用更通用的Date.step 代替循环。例如,

    from_date.step(Date.today, interval) {|d|
        # Each iteration of this block will be passed a value for 'd'
        #   that is 'interval' days after the previous 'd'.
    }
    

    其中interval 是以天为单位的时间长度。

    如果您所做的只是计算经过的时间,那么可能有更好的方法。如果您的日期存储为Date 对象,则执行date - Date.today 将为您提供该日期与现在之间的天数。要计算月、年等,您可以使用以下内容:

    # Parameter 'old_date' must be a Date object
    def months_since(old_date)
        (Date.today.month + (12 * Date.today.year)) - (old_date.month + (12 * old_date.year))
    end
    def years_since(old_date)
        Date.today.year - old_date.year
    end
    def days_since(old_date)
        Date.today - old_date
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 2019-10-28
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多