1

我正在使用ice_cubegem 来创建时间表。从 31 日开始制定每月计划会错过所有少于 31 天的月份。我想在这几个月里安排一个月的最后一天。如果我的日程安排从 30 日开始,我想要每个月的 30 日和 2 月的最后一天。闰年使事情变得更加复杂。

创建处理从 29 日、30 日或 31 日开始的时间表的好方法是什么?

4

4 回答 4

2

这已在最新的 IceCube 中修复:

IceCube::Schedule.new(Time.parse('Oct 31, 2013 9:00am PDT')) do |s|
  s.add_recurrence_rule(IceCube::Rule.monthly(1))
end.first(5)

[2013-10-31 09:00:00 -0700,
 2013-11-30 09:00:00 -0800,
 2013-12-31 09:00:00 -0800,
 2014-01-31 09:00:00 -0800,
 2014-02-28 09:00:00 -0800]
于 2014-10-02T17:03:51.533 回答
0

您可以day_of_month(-1)在本月的最后一天使用。

于 2013-11-03T20:26:18.953 回答
0

您可以像往常一样使用 day_of_month 和 29、30、31 设置时间表。然后使用一个函数来确定哪些月份被跳过并使用单次发生事件来设置它们。诚然,有点 hack,但可以解决 ice_cube 的限制。

这是一个简单的脚本,用于确定在任何给定年份中将跳过哪些月份。

require 'date'
def months_less_than_days(days, year = Date.today.year)
    months = []
    (1..11).each do |m| 
        eom = (Date.new(year, m+1, 1) - 1)
        months << eom if eom.day < days
    end
    eom = (Date.new(year+1, 1, 1) - 1)
    months << eom if eom.day < days
    months
end

puts months_less_than_days(31) # => [2013-02-28, 2013-04-30, 2013-06-30, 2013-09-30, 2013-11-30]
于 2013-11-03T22:20:20.093 回答
0

这通过了我的所有规格,但是很丑陋,并且可能会因超过一年的时间表而中断(我还不关心)。

class LeasePaymentSchedule

  def self.monthly(a bunch of args)
    case start_day

    when 31
      schedule = IceCube::Schedule.new(start, scheduler_options) do |s|
        s.add_recurrence_rule IceCube::Rule.monthly.day_of_month(-1).until(end_time)
      end

    when 30,29
      schedule = IceCube::Schedule.new(start, scheduler_options) do |s|
        s.add_recurrence_rule IceCube::Rule.monthly.day_of_month(start_day).until(end_time)
      end

      schedule.all_occurrences.each do |o|
        next unless [1,3,6,8,10].include? o.month
        missed = (o + 1.month).yday
        # Probably breaks for durations longer than 1 year
        schedule.add_recurrence_rule IceCube::Rule.yearly.day_of_year(missed).count(1)
      end

    else
      schedule = IceCube::Schedule.new(start, scheduler_options) do |s|
        s.add_recurrence_rule IceCube::Rule.monthly.day_of_month(start_day).until(end_time)
      end
    end
    schedule
   end
end

这么多规格:

Finished in 4.17 seconds
390 examples, 0 failures

-

shared_examples_for :a_schedule do
  it 'returns an IceCube Schedule' do
    schedule.should be_a IceCube::Schedule
  end
  it 'should start on the correct day' do
    schedule.start_time.should eq expected_start
  end
  it 'has the right number of occurrences' do
    schedule.all_occurrences.size.should eq expected_occurrences
  end
end

describe :monthly do
  let(:expected_occurrences) { 12 }
  let(:expected_start) { date.next_month.beginning_of_day }
  let(:schedule) { LeasePaymentSchedule.monthly }

  before do
    Date.stub(:today).and_return(date)
  end

  shared_examples_for :on_the_28th do
    let(:date) { Time.parse "#{year}-#{month}-28" }
    it_behaves_like :a_schedule
  end

  shared_examples_for :on_the_29th do
    let(:date) { Time.parse "#{year}-#{month}-29" }
    it_behaves_like :on_the_28th
    it_behaves_like :a_schedule
  end

  shared_examples_for :on_the_30th do
    let(:date) { Time.parse "#{year}-#{month}-30" }
    it_behaves_like :on_the_29th
    it_behaves_like :a_schedule
  end

  shared_examples_for :on_the_31st do
    let(:date) { Time.parse "#{year}-#{month}-31" }
    it_behaves_like :on_the_30th
    it_behaves_like :a_schedule
  end

  shared_examples_for :the_whole_year do
    context :february do
      let(:month) { 2 }
      it_behaves_like :on_the_28th
    end
    [ 4, 7, 9, 11 ].each do |month_num|
      let(:month) { month_num }
      it_behaves_like :on_the_30th
    end
    [ 1, 3, 5, 6, 8, 10, 12].each do |month_num|
      let(:month) { month_num }
      it_behaves_like :on_the_31st
    end
  end

  context :a_leap_year do
    let(:year) { 2012 }
    context :february_29th do
      let(:month) { 2 }
      it_behaves_like :on_the_29th
    end
    it_behaves_like :the_whole_year
  end

  context :before_a_leap_year do
    let(:year) { 2011 }
    it_behaves_like :the_whole_year
  end

  context :nowhere_near_a_leap_year do
    let(:year) { 2010 }
    it_behaves_like :the_whole_year
  end

end
于 2013-11-03T22:32:14.813 回答