Ruby 对于任何给定日期(包括未来),我如何计算X天(如5天)之后的第二天(如周一)?
我一直在为这件事绞尽脑汁 下面是我目前的方法,只适用于过去的日期。如果开始日期是2个月后。。。它不起作用Ruby 对于任何给定日期(包括未来),我如何计算X天(如5天)之后的第二天(如周一)?,ruby,date,datetime,ruby-on-rails-4,Ruby,Date,Datetime,Ruby On Rails 4,我一直在为这件事绞尽脑汁 下面是我目前的方法,只适用于过去的日期。如果开始日期是2个月后。。。它不起作用 def date_of_next_X_day_Y_days_out_from_Z_start(day=ENV['day_to_start_plans'], number_of_days=ENV['min_days_out'], start_date) # Explanation uses Monday as an example # When was the last Mon
def date_of_next_X_day_Y_days_out_from_Z_start(day=ENV['day_to_start_plans'], number_of_days=ENV['min_days_out'], start_date)
# Explanation uses Monday as an example
# When was the last Monday?
date = Date.parse(day)
# Was the last Monday after the start_date? If so, then there's no difference between the last Monday and the next Monday; else, the next Monday is 7 days from the last Monday
delta = date > (start_date) ? 0 : 7
actual_next_day = date + delta
# Is there a minimum of Y number_of_days between the next Monday and the start_date? If not, bump to the following Monday by adding 7 more days
delta_2 = (actual_next_day - start_date) < number_of_days ? 7 : 0
actual_next_day + delta_2 #returned value
end
仅供参考,我确实有rails,所以请随时向advance或change helpers大声呼喊。在纯Ruby中,我就是这样做的
def date_of_next_X_day_Y_days_out_from_Z_start(target_wday, skip, d)
d += skip # add "skip" number of days
# now keep add a day while checking wday (weekday) until we hit our target
# 0 = Monday, ..., 6 = Sunday
(0..6).each do |i|
break if d.wday == target_wday
d += 1
end
puts "Next Tuesday is #{d}"
用法示例:
# Find the next Tuesday (1) 5 days after June 15, 2015
date_of_next_X_day_Y_days_out_from_Z_start(1, 5, Date.parse("June 15,2015"))
将周天数用作星期天的数字0。。。6对于星期六,您可以使用以下公式确定所需日期:
def date_of_next_X_day_Y_days_out_from_Z_start(wday, number_of_days, start_date)
day_ahead = start_date + number_of_days.days
(day_ahead) + ((7 - day_ahead.wday + wday) % 7).days
end
一些测试:
dates = [
{ wday: 1, n_days: 5, start_date: Date.parse('May 23,2015') },
{ wday: 3, n_days: 7, start_date: Date.parse('May 8,2015') },
{ wday: 5, n_days: 3, start_date: Date.parse('June 15,2015') },
{ wday: 3, n_days: 1, start_date: Date.parse('May 13,2015') },
{ wday: 5, n_days: 1, start_date: Date.parse('May 20,2015') }
]
dates.each do |date|
puts date_of_next_X_day_Y_days_out_from_Z_start(date[:wday], date[:n_days], date[:start_date])
end
# => 2015-06-01
# => 2015-05-20
# => 2015-06-19
# => 2015-05-20
# => 2015-05-22
这可能会起作用:
def date_of_next_X_day_Y_days_out_from_Z_start(day=ENV['day_to_start_plans'], number_of_days=ENV['min_days_out'], start_date)
real_start_date = start_date + number_of_days
until real_start_date.wday == Date.parse(day).wday
real_start_date += 1
end
real_start_date
end
根据你目前的方法,问题是你没有考虑到你的开始日期是多少周前的日期,所以你的返回日期是短。您可以计算开始日期的前几周,并对delta_2重复计算,同时不断向其添加条件值。delta_2现在将包括1您的开始日期提前了多少周,2如果实际的下一天的天数少于要跳过的天数,则增加一周
def date_of_next_X_day_Y_days_out_from_Z_start(day=ENV['day_to_start_plans'], number_of_days=ENV['min_days_out'], start_date)
real_start_date = start_date + number_of_days
until real_start_date.wday == Date.parse(day).wday
real_start_date += 1
end
real_start_date
end
def next_date(target_wday, skip_num_days, start_date)
date = Date.parse(target_wday)
delta = date > start_date ? 0 : 7
actual_next_day = date + delta
# define delta_2 so you're able to use +=
delta_2 = 0
# calculates how many weeks ahead the start date is
repeat = (actual_next_day - start_date).to_i % 7
# removes the current week you're calculating
( repeat - 1 ).times do
delta_2 += (actual_next_day - start_date) < skip_num_days ? 7 : 0
end
actual_next_day + delta_2
end