2017-07-01 6 views
1

私は自分のアプリにカレンダーシステムを構築しようとしています。私が現在抱えている問題は、月に一度のスケジュールです。基本的に、ある人がその月の第2水曜日に予定を立てた場合、私はそのスケジュールを翌月の第2水曜日に自動的に更新したいと考えています。私はちょうど+ 1.monthを追加しようとしましたが、それは私が欲しいものを正確に達成しません。それは翌日の曜日ではなく次の月の日に移動するためです。誰も私がこれを達成する方法を知っていますか?ここに私が現在しているのは正しいことではありません。Rubyで月の特定の日を見つけよう

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 

答えて

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) 
+0

ありがとうございました!それは良い解決策でした。ヘルプをよろしくお願いいたします。 – Bitwise

+0

@Bitwise申し訳ありません。しかし、私の解決策はいくつかのケースで間違った結果を与えていました。たとえば、 'specific_day_of_next_month(Date.new(2017、7、10))'などです。ちょうど答え、 'get_week_number(date)'メソッドを更新しました。 –

+0

更新いただきありがとうございます。しかし、私は今このエラーが発生しています.'uninitialized定数NextMonthifyAssignment :: DAYS'私はそれを修正するために何をする必要がありますか? – Bitwise

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はTHS機能をサポートしています。

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 

8月の第2日曜日の日付を取得し、2017

date_of_nth_wday(8, 2017, 0, 2) 
    #=> #<Date: 2017-08-13 ((2457979j,0s,0n),+0s,2299161j)> 

8月の第三金曜日の日付を取得し、2017

date_of_nth_wday(8, 2017, 5, 3) 
    #=> #<Date: 2017-08-18 ((2457984j,0s,0n),+0s,2299161j)> 

8月の第五の月曜日の日付を取得し、2017

date_of_nth_wday(8, 2017, 1, 5) 
    #=> nil (there are only 4 Mondays in August, 2017) 
関連する問題