在我的应用程序中,我有各种日期序列,例如每周,每月和每年。鉴于过去的任意日期,我需要计算序列中的下一个 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'解决方法?或者我应该坚持我的循环以简化这一切?
答案 0 :(得分:15)
因为您将此问题标记为ruby-on-rails
,所以我认为您使用的是Rails。
ActiveSupport引入了calculation模块,该模块提供了有用的#advance
方法。
date = Date.today
date.advance(:weeks => 1)
date.advance(:days => 7)
# => next week
答案 1 :(得分:4)
我过去曾使用recurrence gem来达到此目的。还有一些其他宝石可以模拟here列出的重复事件。
答案 2 :(得分:2)
如果您使用Time
对象,则可以使用Time.to_a
将时间分解为数组(包含表示小时,日,月等的字段),调整相应字段,以及将数组传递回Time.local
或Time.utc
以构建新的Time
对象。
如果您使用的是Date
课程,date +/- n
会在n天后/更早的时间给您一个日期,date >>/<< 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