我试图将日历系统构建到我的应用程序中。我目前所处的问题是每月一次。基本上,如果一个人在该月的第二个星期三安排,我想自动将时间表更新到下个月的第二个星期三。我尝试过添加+ 1.month
,但这并没有达到我想要的效果。因为它将它移动到下个月的日期而不是一周中的某一天。有谁知道我怎么能做到这一点。以下是我目前正在做的事情,这是不对的。
def call
schedule.update!(
end_at: end_at_next_month,
start_at: start_at_next_month,
status: "monthly",
arranged: true
)
end
private
def schedule
context.schedule
end
def end_at_next_month
schedule.end_at + 1.month
end
def start_at_next_month
schedule.start_at + 1.month
end
end
答案 0 :(得分:2)
require 'date'
def date_of_nth_wday(month, year, wday, nth)
base_date = Date.new(year, month)
base_wday = base_date.wday
ret_date = base_date +
( wday > base_wday ? wday - base_wday : 7 - base_wday + wday) +
7*(nth-1)
ret_date.month == month ? ret_date : nil
end
获取2017年8月第二个星期日的日期
date_of_nth_wday(8, 2017, 0, 2)
#=> #<Date: 2017-08-13 ((2457979j,0s,0n),+0s,2299161j)>
获取2017年8月第三个星期五的日期
date_of_nth_wday(8, 2017, 5, 3)
#=> #<Date: 2017-08-18 ((2457984j,0s,0n),+0s,2299161j)>
获取2017年8月第五个星期一的日期
date_of_nth_wday(8, 2017, 1, 5)
#=> nil (there are only 4 Mondays in August, 2017)
答案 1 :(得分:1)
您可以尝试这样的事情:
DAYS_MAPPING = { 0=>"Sunday",
1=>"Monday",
2=>"Tuesday",
3=>"Wednesday",
4=>"Thursday",
5=>"Friday",
6=>"Saturday" }
# Returns week of month in integer
# for example: 1 for matching day of 1st week of the month
def get_week_number(date)
week_number = date.strftime('%U').to_i - date.beginning_of_month.strftime('%U').to_i
offset = (Date.parse(DAYS_MAPPING[date.wday]) < date.beginning_of_month) ? 0 : 1
week_number + offset
end
def specific_day_of_next_month(schedule)
# wday => day of week in integer
# for example: 0 for Sunday; 1 for Monday & so on ...
wday = schedule.wday
week_number = get_week_number(schedule)
next_month = schedule + 1.month
days = (next_month.beginning_of_month..next_month.end_of_month).select { |d| d.wday == wday }
days[week_number-1]
end
示例1:
schedule = Date.today
# => Sat, 01 Jul 2017 (First Saturday of July)
specific_day_of_next_month(schedule)
# => Sat, 05 Aug 2017 (First Saturday of August)
示例2:
schedule = Date.new(2017, 7, 10)
# => Mon, 10 Jul 2017 (Second Monday of July)
specific_day_of_next_month(schedule)
# => Mon, 14 Aug 2017 (Second Monday of August)
答案 2 :(得分:0)
您的标题与文中的说明不同。以我的例子你没有得到上周五,但你可以选择一个月的1,2,3,4,5周三(或任何其他日子)。
require 'date'
class Date
#~ class DateError < ArgumentError; end
#Get the third monday in march 2008: new_by_mday( 2008, 3, 1, 3)
#
#Based on http://forum.ruby-portal.de/viewtopic.php?f=1&t=6157
def self.new_by_mday(year, month, weekday, nr)
raise( ArgumentError, "No number for weekday/nr") unless weekday.respond_to?(:between?) and nr.respond_to?(:between?)
raise( ArgumentError, "Number not in Range 1..5: #{nr}") unless nr.between?(1,5)
raise( ArgumentError, "Weekday not between 0 (Sunday)and 6 (Saturday): #{nr}") unless weekday.between?(0,6)
day = (weekday-Date.new(year, month, 1).wday)%7 + (nr-1)*7 + 1
if nr == 5
lastday = (Date.new(year, (month)%12+1, 1)-1).day # each december has the same no. of days
raise "There are not 5 weekdays with number #{weekday} in month #{month}" if day > lastday
end
Date.new(year, month, day)
end
end
#2nd monday (weekday 1) in july
p Date.new_by_mday(2017,7,1,2)
如果你寻找宝石:date_tools支持这个功能。