4

基本上我有一个应用程序,用户可以在其中选择从现在到 2 年后的任何一天的时间段。我正在创建一个每天运行的 rake 任务,以便从现在起 2 年内向我的数据库中添加一条记录,这样明天,仍然有 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 月 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 设置为在每个月的第一天运行,并在该月的每一天循环。这将包括闰年的 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 回答