Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: ootoovak/ice_cube
base: 05f8677efe
...
head fork: ootoovak/ice_cube
compare: f9a27f5a52
  • 12 commits
  • 18 files changed
  • 0 commit comments
  • 2 contributors
View
12 CHANGELOG
@@ -68,6 +68,14 @@
0.7.6
* Support for #terminating? and #conflicts_with?
----
+0.7.7
+ * Added "Weekends" and "Weekdays" to #day's to_s
-* Added "Weekends" and "Weekdays" to #day's to_s
+0.7.8
+ * Bug fixes
+
+0.7.9
+ * Added INTERVAL to to_ical for all interval validations
+
+0.8.0
+ * Added support for WEEKST (thanks @devwout)
View
7 README.md
@@ -28,8 +28,11 @@ schedule.add_recurrence_rule Rule.yearly.day_of_month(13).day(:friday).
## Quick Introductions
* Presentation from Lone Star Ruby Conf -
- http://seejohncode.com/ice_cube/static/ice_cube_ruby_nyc.pdf
-* Quick Introduction - http://seejohncode.com/ice_cube/
+ http://seejohnrun.github.com/ice_cube/static/lsrc_ice_cube.pdf
+* Quick Introduction -
+ http://seejohnrun.github.com/ice_cube/static/ice_cube_ruby_nyc.pdf
+* Website -
+ http://seejohnrun.github.com/ice_cube/
---
View
2  lib/ice_cube.rb
@@ -73,7 +73,7 @@ module Validations
TO_S_TIME_FORMAT = '%B %e, %Y'
def self.use_psych?
- @use_psych ||= defined?(Psych) && Psych::VERSION
+ @use_psych ||= defined?(Psych) && defined?(Psych::VERSION)
end
end
View
4 lib/ice_cube/rule.rb
@@ -97,8 +97,8 @@ def daily(interval = 1)
end
# Weekly Rule
- def weekly(interval = 1)
- WeeklyRule.new(interval)
+ def weekly(interval = 1, week_start = :sunday)
+ WeeklyRule.new(interval, week_start)
end
# Monthly Rule
View
4 lib/ice_cube/rules/weekly_rule.rb
@@ -4,8 +4,8 @@ class WeeklyRule < ValidatedRule
include Validations::WeeklyInterval
- def initialize(interval = 1)
- interval(interval)
+ def initialize(interval = 1, week_start = :sunday)
+ interval(interval, week_start)
schedule_lock(:wday, :hour, :min, :sec)
end
View
15 lib/ice_cube/schedule.rb
@@ -302,6 +302,13 @@ def self.from_hash(data, options = {})
data[:extimes] && data[:extimes].each do |t|
schedule.add_exception_time TimeUtil.deserialize_time(t)
end
+ # Also serialize old format for backward compat
+ data[:rdates] && data[:rdates].each do |t|
+ schedule.add_recurrence_time TimeUtil.deserialize_time(t)
+ end
+ data[:exdates] && data[:exdates].each do |t|
+ schedule.add_exception_time TimeUtil.deserialize_time(t)
+ end
schedule
end
@@ -311,6 +318,14 @@ def terminating?
end_time || recurrence_rules.all?(&:terminating?)
end
+ def self.dump(schedule)
+ schedule.to_yaml
+ end
+
+ def self.load(yaml)
+ from_yaml(yaml) unless yaml.nil? || yaml.empty?
+ end
+
private
# Reset all rules for another run
View
16 lib/ice_cube/time_util.rb
@@ -64,6 +64,18 @@ def self.symbol_to_day(sym)
day
end
+ # Convert a symbol to an ical day (SU, MO)
+ def self.week_start(sym)
+ raise "No such day: #{sym}" unless DAYS.keys.include?(sym)
+ day = sym.to_s.upcase[0..1]
+ day
+ end
+
+ # Convert weekday from base sunday to the schedule's week start.
+ def self.normalize_weekday(daynum, week_start)
+ (daynum - symbol_to_day(week_start)) % 7
+ end
+
# Return the count of the number of times wday appears in the month,
# and which of those time falls on
def self.which_occurrence_in_month(time, wday)
@@ -93,7 +105,7 @@ def self.days_in_next_month(time)
def self.days_in_month_year(month, year)
is_leap?(year) ? LEAP_YEAR_MONTH_DAYS[month - 1] : COMMON_YEAR_MONTH_DAYS[month - 1]
end
-
+
# Number of days in a year
def self.days_in_year(time)
is_leap?(time.year) ? 366 : 365
@@ -190,7 +202,7 @@ def adjust(&block)
yield
end
end
-
+
def clear_sec
@time -= @time.sec
end
View
3  lib/ice_cube/validations/daily_interval.rb
@@ -29,6 +29,9 @@ def build_hash(builder)
def build_ical(builder)
builder['FREQ'] << 'DAILY'
+ unless interval == 1
+ builder['INTERVAL'] << interval
+ end
end
def type
View
5 lib/ice_cube/validations/hourly_interval.rb
@@ -6,7 +6,7 @@ def interval(interval)
validations_for(:interval) << Validation.new(interval)
clobber_base_validations(:hour)
self
- end
+ end
class Validation
@@ -26,6 +26,9 @@ def build_hash(builder)
def build_ical(builder)
builder['FREQ'] << 'HOURLY'
+ unless interval == 1
+ builder['INTERVAL'] << interval
+ end
end
def initialize(interval)
View
3  lib/ice_cube/validations/minutely_interval.rb
@@ -26,6 +26,9 @@ def build_s(builder)
def build_ical(builder)
builder['FREQ'] << 'MINUTELY'
+ unless interval == 1
+ builder['INTERVAL'] << interval
+ end
end
def build_hash(builder)
View
3  lib/ice_cube/validations/monthly_interval.rb
@@ -22,6 +22,9 @@ def build_s(builder)
def build_ical(builder)
builder['FREQ'] << 'MONTHLY'
+ unless interval == 1
+ builder['INTERVAL'] << interval
+ end
end
def build_hash(builder)
View
3  lib/ice_cube/validations/secondly_interval.rb
@@ -26,6 +26,9 @@ def build_s(builder)
def build_ical(builder)
builder['FREQ'] << 'SECONDLY'
+ unless interval == 1
+ builder['INTERVAL'] << interval
+ end
end
def build_hash(builder)
View
19 lib/ice_cube/validations/weekly_interval.rb
@@ -4,14 +4,15 @@ module IceCube
module Validations::WeeklyInterval
- def interval(interval)
- validations_for(:interval) << Validation.new(interval)
+ def interval(interval, week_start = :sunday)
+ validations_for(:interval) << Validation.new(interval, week_start)
clobber_base_validations(:day)
+ self
end
class Validation
- attr_reader :interval
+ attr_reader :interval, :week_start
def type
:day
@@ -23,21 +24,29 @@ def build_s(builder)
def build_ical(builder)
builder['FREQ'] << 'WEEKLY'
+ unless interval == 1
+ builder['INTERVAL'] << interval
+ builder['WKST'] << TimeUtil.week_start(week_start)
+ end
end
def build_hash(builder)
builder[:interval] = interval
end
- def initialize(interval)
+ def initialize(interval, week_start)
@interval = interval
+ @week_start = week_start
end
def validate(time, schedule)
date = Date.new(time.year, time.month, time.day)
st = schedule.start_time
start_date = Date.new(st.year, st.month, st.day)
- weeks = ((date - date.wday) - (start_date - start_date.wday)) / 7
+ weeks = (
+ (date - TimeUtil.normalize_weekday(date.wday, week_start)) -
+ (start_date - TimeUtil.normalize_weekday(start_date.wday, week_start))
+ ) / 7
unless weeks % interval == 0
(interval - (weeks % interval)) * 7
end
View
3  lib/ice_cube/validations/yearly_interval.rb
@@ -25,6 +25,9 @@ def build_hash(builder)
def build_ical(builder)
builder['FREQ'] << 'YEARLY'
+ unless interval == 1
+ builder['INTERVAL'] << interval
+ end
end
def initialize(interval)
View
2  lib/ice_cube/version.rb
@@ -1,5 +1,5 @@
module IceCube
- VERSION = '0.7.7'
+ VERSION = '0.8.0'
end
View
30 spec/examples/serialization_spec.rb
@@ -0,0 +1,30 @@
+require 'active_support/time'
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe IceCube::Schedule do
+ let(:schedule) { IceCube::Schedule.new Time.now }
+ let(:yaml) { described_class.dump(schedule) }
+
+ describe '::dump(schedule)' do
+ it 'serializes a Schedule object as YAML string' do
+ yaml.should be_a_kind_of String
+ end
+ end
+
+ describe '::load(yaml)' do
+ let(:new_schedule) { described_class.load yaml }
+
+ it 'creates a new object from a YAML string' do
+ new_schedule.start_time.should eq schedule.start_time
+ end
+
+ context 'when yaml is blank' do
+ let(:yaml) { nil }
+
+ it 'returns nil' do
+ new_schedule.should be_nil
+ end
+ end
+ end
+end
+
View
50 spec/examples/to_ical_spec.rb
@@ -37,52 +37,52 @@
rule = IceCube::Rule.secondly
rule.to_ical.should == "FREQ=SECONDLY"
end
-
+
it 'should be able to serialize a .day rule to_ical' do
rule = IceCube::Rule.daily.day(:monday, :tuesday)
rule.to_ical.should == "FREQ=DAILY;BYDAY=MO,TU"
end
-
+
it 'should be able to serialize a .day_of_week rule to_ical' do
rule = IceCube::Rule.daily.day_of_week(:tuesday => [-1, -2])
rule.to_ical.should == "FREQ=DAILY;BYDAY=-1TU,-2TU"
end
-
+
it 'should be able to serialize a .day_of_month rule to_ical' do
rule = IceCube::Rule.daily.day_of_month(23)
rule.to_ical.should == "FREQ=DAILY;BYMONTHDAY=23"
end
-
+
it 'should be able to serialize a .day_of_year rule to_ical' do
rule = IceCube::Rule.daily.day_of_year(100,200)
rule.to_ical.should == "FREQ=DAILY;BYYEARDAY=100,200"
end
-
+
it 'should be able to serialize a .month_of_year rule to_ical' do
rule = IceCube::Rule.daily.month_of_year(:january, :april)
rule.to_ical.should == "FREQ=DAILY;BYMONTH=1,4"
end
-
+
it 'should be able to serialize a .hour_of_day rule to_ical' do
rule = IceCube::Rule.daily.hour_of_day(10, 20)
rule.to_ical.should == "FREQ=DAILY;BYHOUR=10,20"
end
-
+
it 'should be able to serialize a .minute_of_hour rule to_ical' do
rule = IceCube::Rule.daily.minute_of_hour(5, 55)
rule.to_ical.should == "FREQ=DAILY;BYMINUTE=5,55"
end
-
+
it 'should be able to serialize a .second_of_minute rule to_ical' do
rule = IceCube::Rule.daily.second_of_minute(0, 15, 30, 45)
rule.to_ical.should == "FREQ=DAILY;BYSECOND=0,15,30,45"
end
-
+
it 'should be able to collapse a combination day_of_week and day' do
rule = IceCube::Rule.daily.day(:monday, :tuesday).day_of_week(:monday => [1, -1])
['FREQ=DAILY;BYDAY=TU,1MO,-1MO', 'FREQ=DAILY;BYDAY=1MO,-1MO,TU'].include?(rule.to_ical).should be(true)
end
-
+
it 'should be able to serialize of .day_of_week rule to_ical with multiple days' do
rule = IceCube::Rule.daily.day_of_week(:monday => [1, -1], :tuesday => [2]).day(:wednesday)
[
@@ -125,7 +125,7 @@
expectation << "RRULE:FREQ=HOURLY"
schedule.to_ical.should == expectation
end
-
+
it 'should be able to serialize a schedule with one exrule' do
Time.zone ='Pacific Time (US & Canada)'
schedule = IceCube::Schedule.new(Time.zone.local(2010, 5, 10, 9, 0, 0))
@@ -135,7 +135,7 @@
expectation<< 'EXRULE:FREQ=WEEKLY'
schedule.to_ical.should == expectation
end
-
+
it 'should be able to serialize a schedule with multiple exrules' do
Time.zone ='Eastern Time (US & Canada)'
schedule = IceCube::Schedule.new(Time.zone.local(2010, 10, 20, 4, 30, 0))
@@ -146,7 +146,7 @@
expectation<< "EXRULE:FREQ=HOURLY"
schedule.to_ical.should == expectation
end
-
+
it 'should be able to serialize a schedule with an rdate' do
schedule = IceCube::Schedule.new(Time.utc(2010, 5, 10, 10, 0, 0))
schedule.add_recurrence_date Time.utc(2010, 6, 20, 5, 0, 0)
@@ -171,7 +171,7 @@
expectation << 'DURATION:PT1H'
schedule.to_ical.should == expectation
end
-
+
it 'should be able to serialize a schedule with a duration - more odd duration' do
schedule = IceCube::Schedule.new(Time.utc(2010, 5, 10, 10), :duration => 3665)
expectation = "DTSTART:20100510T100000Z\n"
@@ -215,5 +215,25 @@
rule = IceCube::Rule.weekly.count(5)
rule.to_ical.should match /^FREQ=WEEKLY;COUNT=5$/
end
-
+
+ %w{secondly minutely hourly daily monthly yearly}.each do |mthd|
+ it "should include intervals for #{mthd} rule" do
+ interval = 2
+ rule = IceCube::Rule.send(mthd.to_sym, interval)
+ rule.to_ical.should == "FREQ=#{mthd.upcase};INTERVAL=#{interval}"
+ end
+ end
+
+ it 'should include intervals for weekly rule, including weekstart' do
+ interval = 2
+ rule = IceCube::Rule.send(:weekly, interval)
+ rule.to_ical.should == "FREQ=WEEKLY;INTERVAL=#{interval};WKST=SU"
+ end
+
+ it 'should include intervals for weekly rule, including custom weekstart' do
+ interval = 2
+ rule = IceCube::Rule.send(:weekly, interval, :monday)
+ rule.to_ical.should == "FREQ=WEEKLY;INTERVAL=#{interval};WKST=MO"
+ end
+
end
View
18 spec/examples/weekly_rule_spec.rb
@@ -36,7 +36,7 @@
dates = schedule.occurrences(start_date + 7*3*IceCube::ONE_DAY)
dates.should == [start_date, start_date + 14*IceCube::ONE_DAY]
end
-
+
it 'should occurr every 2nd tuesday of a month' do
now = Time.now
schedule = IceCube::Schedule.new(Time.local(now.year, now.month, now.day))
@@ -46,7 +46,7 @@
d.wday.should == 2
end
end
-
+
it 'should occur on every first day of a month at midnight and not skip months when DST ends' do
start_date = Time.local(2011, 8, 1)
[:sunday, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday].each_with_index do |day, index|
@@ -73,5 +73,17 @@
schedule.add_recurrence_rule IceCube::Rule.weekly.day(:monday)
schedule.first(3).should == [Time.local(2010, 8, 2), Time.local(2010, 8, 9), Time.local(2010, 8, 16)]
end
-
+
+ it 'should start weekly rules on monday when monday is the week start' do
+ schedule = IceCube::Schedule.new(Time.local(2012,2,7))
+ schedule.add_recurrence_rule IceCube::Rule.weekly(2, :monday).day(:tuesday, :sunday)
+ schedule.first(3).should == [Time.local(2012,2,7), Time.local(2012,2,12), Time.local(2012,2,21)]
+ end
+
+ it 'should start weekly rules on sunday by default' do
+ schedule = IceCube::Schedule.new(Time.local(2012,2,7))
+ schedule.add_recurrence_rule IceCube::Rule.weekly(2).day(:tuesday, :sunday)
+ schedule.first(3).should == [Time.local(2012,2,7), Time.local(2012,2,19), Time.local(2012,2,21)]
+ end
+
end

No commit comments for this range

Something went wrong with that request. Please try again.