4

基本的に私は、ユーザーが今から2年後までの任意の日のタイムスロットを選択できるアプリを持っています。私は、データベースにレコードを追加するために毎日実行されるrakeタスクを作成しているので、明日も2年分のタイムスロットの選択肢があります。

私の現在のロジックでは、うるう年が発生したときに何が起こるかについて興味があります。うるう年を正しく処理するために、これをより堅牢にする方法はありますか?完全に見落とされる日、または重複する日になるのではないかと心配しています。

task :generate_timeslots => :environment do

    startDate = Time.now.to_date + 2.years
    endDate = Time.now.to_date + 2.years

    startDate.upto(endDate).each do |d|

    5.times do  
       timeslot = Timeslot.create
       timeslot.location_id = 1
       timeslot.timeslot = "#{d} 09:00:00"
       timeslot.save

       timeslot = Timeslot.create
       timeslot.location_id = 1
       timeslot.timeslot = "#{d} 11:00:00"
       timeslot.save

       timeslot = Timeslot.create
       timeslot.location_id = 1
       timeslot.timeslot = "#{d} 13:00:00"
       timeslot.save

       timeslot = Timeslot.create
       timeslot.location_id = 1
       timeslot.timeslot = "#{d} 15:00:00"
       timeslot.save
    end
    end
end
4

5 に答える 5

3

答えは、 「今から2年後」にうるう年の2月29日の日付を超えることが含まれる場合、カレンダーの2月29日の「余分な」日を考慮して「余分な」日がそのバックアップに含まれるということです。

于 2013-03-25T03:40:19.987 に答える
0

タスクがべき等に動作する場合、誤って多くのスロットを作成する心配はありません。

Timeslot.createを呼び出す前に、スクリプトを変更して重複する日を生成する可能性がありますが、スロットを選択してカウントすることにより、スロットがすでに十分にある場合は生成しません。これには、実行を逃した場合に(わずかに)堅牢になり、スクリプトが頻繁に実行される場合にはるかに堅牢になるという追加の利点があります。

使用しているORMがわからないため、これの一部を擬似コードとして扱う必要があります。

task :generate_timeslots => :environment do

  startDate = Time.now.to_date + 2.years - 2.days
  endDate = Time.now.to_date + 2.years

  startDate.upto(endDate).each do |d|

  daily_slots = ["09:00:00","11:00:00","13:00:00","15:00:00"]

  daily_slots.each do |daily_slot|
    ts = "#{d} #{daily_slot}"

    # I'm just guessing here (no ActiveRecord experience)
    num_existing = Timeslot.where( :timeslot => ts ).count

    next if num_existing >=5 

    (5-num_existing).times do  
       timeslot = Timeslot.create
       timeslot.location_id = 1
       timeslot.timeslot = ts
       timeslot.save
    end
  end
end
于 2013-04-01T09:52:16.070 に答える
0

実際の飛躍日を4年先に送信して、バグの反対側を修正することができます。私の飛躍日は事前に入力されません

このソリューションは、数十年にわたって正確です(テーブルに入力する時間に関連するデータがない場合)。

于 2013-04-03T11:45:45.953 に答える
0

ええと、うるう年if (!(year % 100) == 0 || (year % 400 == 0)) && (year % 4 == 0)です。これはまったくRailsの構文ではありませんが、この一口をディスカッションに挿入すると思いました。

于 2013-04-03T15:43:27.270 に答える
0

これが私が思いついたものです。毎日日付を入力する代わりに、cronを毎月1日に実行し、その月の毎日ループするように設定します。これには、うるう年の2月29日が含まれます。

startDate       = (Time.now.beginning_of_month.to_date) + 2.years
endDate         = ((Time.now.beginning_of_month.to_date) + 2.years).end_of_month

startDate.upto(endDate).each do |d|

        5.times do

           timeslot = Timeslot.create
           timeslot.location_id = 1
           timeslot.timeslot = "#{d} 09:00:00"
           timeslot.save

           timeslot = Timeslot.create
           timeslot.location_id = 1
           timeslot.timeslot = "#{d} 11:00:00"
           timeslot.save

           timeslot = Timeslot.create
           timeslot.location_id = 1
           timeslot.timeslot = "#{d} 13:00:00"
           timeslot.save

           timeslot = Timeslot.create
           timeslot.location_id = 1
           timeslot.timeslot = "#{d} 15:00:00"
           timeslot.save
        end
end
于 2013-04-03T20:30:16.320 に答える