recurring 0.3.2 → 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.3.5 / 2006-12-14
2
+
3
+ * documentation / hoe
4
+
1
5
  == 0.3.2 / 2006-12-13
2
6
 
3
7
  * initialization bugfixes
data/Rakefile CHANGED
@@ -25,7 +25,6 @@ Hoe.new('recurring', Recurring::VERSION) do |p|
25
25
  p.description =<<-DESC
26
26
  Recurring allows you to define Schedules, which can tell you whether or not a given Time falls in the Schedule, as well as being able to return a list of times which match the Schedule within a given range.
27
27
  DESC
28
- puts p.changes
29
28
  end
30
29
 
31
30
  # specification = Gem::Specification.new do |s|
@@ -52,17 +51,17 @@ end
52
51
  # pkg.need_tar = true
53
52
  # end
54
53
  #
55
- # Rake::RDocTask.new(:docs) do |rd|
56
- # rd.main = "README.txt"
57
- # rd.options << '-d' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/
58
- # rd.rdoc_dir = 'doc'
59
- # files = ["History.txt", "README.txt", "Rakefile", "lib/recurring.rb", "spec/recurring_spec.rb"]
60
- # rd.rdoc_files.push(*files)
61
- #
62
- # title = "#{specification.name}-#{specification.version} Documentation"
63
- # #title = "#{rubyforge_name}'s " + title if rubyforge_name != title
64
- #
65
- # rd.options << "-t #{title}"
66
- # end
54
+ Rake::RDocTask.new(:docs) do |rd|
55
+ rd.main = "README.txt"
56
+ rd.options << '-d' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/
57
+ rd.rdoc_dir = 'doc'
58
+ files = ["History.txt", "README.txt", "Rakefile", "lib/recurring.rb", "spec/recurring_spec.rb"]
59
+ rd.rdoc_files.push(*files)
60
+
61
+ title = "Recurring-#{VERSION} Documentation"
62
+ #title = "#{rubyforge_name}'s " + title if rubyforge_name != title
63
+
64
+ rd.options << "-t #{title}"
65
+ end
67
66
 
68
67
 
data/lib/recurring.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Recurring
2
- VERSION = '0.3.2'
3
-
2
+ VERSION = '0.3.10'
4
3
  class << self
4
+
5
5
  # returns a number starting with 1
6
6
  def week_in_month date
7
7
  (((date.day - 1).to_f / 7.0) + 1).floor
@@ -45,8 +45,8 @@ module Recurring
45
45
 
46
46
  attr_reader :unit, :frequency, :anchor, :months, :weeks, :monthdays, :weekdays, :times
47
47
 
48
- # * options is a hash with keys <tt>:unit, :frequency, :anchor, :weeks, :monthdays, :weekdays, :times</tt>
49
- # * valid units are <tt>years, months, weeks, days, hours, and minutes</tt>
48
+ # Options hash has keys <tt>:unit, :frequency, :anchor, :weeks, :monthdays, :weekdays, :times</tt>
49
+ # * valid values for :unit are <tt>years, months, weeks, days, hours, minutes</tt>
50
50
  # * :frequency defaults to 1
51
51
  # * :anchor is required if the frequency is other than one
52
52
  # * :weeks alongside :weekdays is used to specify the nth instance of a weekday in a month.
@@ -64,11 +64,19 @@ module Recurring
64
64
  @frequency = options[:frequency] || 1
65
65
  @anchor = options[:anchor]
66
66
  @times = parse_times options[:times]
67
- @months = Array(options[:months]).collect{|d|d.to_s.downcase.to_sym} if options[:months]
68
- @weeks = Array(options[:weeks]) if options[:weeks]
69
- @weekdays = Array(options[:weekdays]).collect{|d|d.to_s.downcase.to_sym} if options[:weekdays]
70
- @monthdays = Array(options[:monthdays]) if options[:monthdays]
67
+ if options[:months]
68
+ @months = Array(options[:months]).collect{|d|d.to_s.downcase.to_sym}
69
+ raise ArgumentError, 'provide valid months' unless @months.all?{|m|ordinal_month(m)}
70
+ end
71
+
72
+ @weeks = Array(options[:weeks]).collect{|n|n.to_i} if options[:weeks]
73
+ if options[:weekdays]
74
+ @weekdays = Array(options[:weekdays]).collect{|d|d.to_s.downcase.to_sym}
75
+ raise ArgumentError, 'provide valid weekdays' unless @weekdays.all?{|w|ordinal_weekday(w)}
76
+ end
77
+ @monthdays = Array(options[:monthdays]).collect{|n|n.to_i} if options[:monthdays]
71
78
 
79
+
72
80
  @anchor_multiple = options[:times].nil? && options[:weeks].nil? && options[:weekdays].nil? && options[:monthdays].nil?
73
81
  end
74
82
 
@@ -100,6 +108,7 @@ module Recurring
100
108
  def find_next date
101
109
  loop do
102
110
  return date if include?(date)
111
+ #puts "#{@resolution} : #{date}"
103
112
  date = beginning_of_next @resolution, date
104
113
  end
105
114
  end
@@ -108,6 +117,7 @@ module Recurring
108
117
  def find_previous date
109
118
  loop do
110
119
  return date if include?(date)
120
+ #puts "#{@resolution} : #{date}"
111
121
  date = end_of_previous @resolution, date
112
122
  end
113
123
  end
@@ -153,7 +163,7 @@ module Recurring
153
163
  when :week
154
164
  to_sunday = date.wday
155
165
  previous_week = (date - to_sunday*24*60*60)
156
- Time.utc(previous_week.year, previous_week.month, previous_week.day)
166
+ Time.utc(previous_week.year, previous_week.month, previous_week.day) - 1
157
167
  when :day
158
168
  Time.utc(date.year, date.month, date.day) - 1
159
169
  when :time
@@ -179,6 +189,10 @@ module Recurring
179
189
  Time.utc(dayp.year, dayp.month, dayp.day)
180
190
  when :time
181
191
  next_time date
192
+ when :hour
193
+ date.hour < 23 ? Time.utc(date.year, date.month, date.day, date.hour+1) : beginning_of_next(:day, date)
194
+ when :sub_hour
195
+ next_sub_hour date
182
196
  else
183
197
  date + 1
184
198
  end
@@ -221,6 +235,23 @@ module Recurring
221
235
  end
222
236
  end
223
237
 
238
+ def next_sub_hour date
239
+ me = {:minute => date.min, :second => date.sec, :me => true}
240
+ my_times = times + [me]
241
+ my_times += [{:minute => @anchor.min, :second => @anchor.sec}] if check_anchor?
242
+ my_times.sort! do |a,b|
243
+ v = a[:minute] <=> b[:minute]
244
+ v = a[:second] <=> b[:second] if v == 0
245
+ v
246
+ end
247
+ ntime = my_times[my_times.index(me)+1]
248
+ if ntime
249
+ Time.utc(date.year, date.month, date.day, date.hour, ntime[:minute], ntime[:second])
250
+ else
251
+ beginning_of_next :hour, date
252
+ end
253
+ end
254
+
224
255
  def mismatch unit
225
256
  @resolution = unit
226
257
  false
@@ -246,9 +277,9 @@ module Recurring
246
277
  end
247
278
 
248
279
  def week_matches? date
249
- if @unit == :weeks
280
+ if @unit == :weeks
250
281
  return true if @frequency == 1
251
- return (Recurring.week_of_year(date) - Recurring.week_of_year(@anchor)) % @frequency == 0
282
+ return ((Recurring.week_of_year(date) - Recurring.week_of_year(@anchor)) % @frequency) == 0
252
283
  end
253
284
  if @weeks
254
285
  @weeks.include?(Recurring.week_in_month(date))
@@ -325,7 +356,8 @@ module Recurring
325
356
  4 => [:thursday, :thurs],
326
357
  5 => [:friday, :fri],
327
358
  6 => [:saturday, :sat]}
328
- lookup.select{|k,v| v.include?(symbol)}.first.first
359
+ pair = lookup.select{|k,v| v.include?(symbol)}.first
360
+ pair.first if pair
329
361
  end
330
362
 
331
363
  def ordinal_month symbol
@@ -341,7 +373,8 @@ module Recurring
341
373
  10 => [:october, :oct],
342
374
  11 => [:november, :nov],
343
375
  12 => [:december, :dec]}
344
- lookup.select{|k,v| v.include?(symbol)}.first.first
376
+ pair = lookup.select{|k,v| v.include?(symbol)}.first
377
+ pair.first if pair
345
378
  end
346
379
 
347
380
  def parse_times string
@@ -356,7 +389,8 @@ module Recurring
356
389
  time[:hour], time[:minute], time[:second] = st.split(':').collect {|n| n.to_i}
357
390
  time[:minute] ||= 0
358
391
  time[:second] ||= 0
359
- time[:hour] = time[:hour] + 12 if am_pm == 'pm'
392
+ time[:hour] = time[:hour] + 12 if am_pm == 'pm' && time[:hour] < 12
393
+ time[:hour] = 0 if am_pm == 'am' && time[:hour] == 12
360
394
  time
361
395
  end
362
396
  #this is an implementation of Array#uniq required because Hash#eql? is not a synonym for Hash#==
@@ -34,6 +34,18 @@ context "Initializing a Schedule" do
34
34
  rs.times.should == [{:hour => 16, :minute => 30, :second => 0}, {:hour => 17, :minute => 0, :second => 0}, {:hour => 3, :minute => 30, :second => 30}]
35
35
  end
36
36
 
37
+ specify "should not add 12 hours to '12pm'" do
38
+ rs = Recurring::Schedule.new :unit => 'days', :times => '12pm'
39
+ rs.times.should == [{:hour => 12, :minute => 0, :second => 0}]
40
+ end
41
+
42
+ specify "should subtract 12 hours from '12am'" do
43
+ rs = Recurring::Schedule.new :unit => 'days', :times => '12am'
44
+ rs.times.should == [{:hour => 0, :minute => 0, :second => 0}]
45
+ end
46
+
47
+
48
+
37
49
  specify "should be graceful about a duplicate times string" do
38
50
  rs = Recurring::Schedule.new :unit => 'days', :times => '4:30 4:30'
39
51
  rs.times.should == [{:hour => 4, :minute => 30, :second => 0}]
@@ -64,12 +76,25 @@ context "Initializing a Schedule" do
64
76
  rs.weekdays.should == [:monday, :wednesday]
65
77
  end
66
78
 
79
+ specify "should flip out if weekdays aren't in the white list" do
80
+ lambda{Recurring::Schedule.new :unit => 'months', :weeks => [1,2], :weekdays => %w{garbage_day thanksgiving}}.should_raise ArgumentError
81
+ end
82
+
83
+ specify "should flip out if months aren't in the white list" do
84
+ lambda{Recurring::Schedule.new :unit => 'years', :months => %w{monsoon ramadan}, :weeks => [1,2], :weekdays => %w{mon}}.should_raise ArgumentError
85
+ end
86
+
67
87
  specify "should accept months params" do
68
88
  rs = Recurring::Schedule.new :unit => 'years', :months => 'feb', :monthdays => [4]
69
89
  rs.months.should == [:feb]
70
90
  end
71
91
 
72
- specify "should accept days as integers" do
92
+ specify "should accept monthdays as strings" do
93
+ rs = Recurring::Schedule.new :unit => 'months', :monthdays => ['1','15']
94
+ rs.monthdays.should == [1,15]
95
+ end
96
+
97
+ specify "should accept monthdays as integers" do
73
98
  rs = Recurring::Schedule.new :unit => 'months', :monthdays => [1,15]
74
99
  rs.monthdays.should == [1,15]
75
100
  end
@@ -320,6 +345,49 @@ end
320
345
 
321
346
  #WEEKLY
322
347
 
348
+ context "A bi-weekly schedule with weekdays and a midnight time" do
349
+ setup do
350
+ @rs = Recurring::Schedule.new :unit => 'weeks', :weekdays => %w{sat sunday}, :times => '12am', :frequency => 2, :anchor => Time.utc(2001)
351
+ @danger = Time.utc(2006,12,17,18)
352
+ end
353
+
354
+ specify "should include midnights of every other weekend" do
355
+ @rs.should_include Time.utc(2006,12,16)
356
+ @rs.should_include Time.utc(2006,12,10)
357
+ end
358
+
359
+ specify "should not include other midnights" do
360
+ @rs.should_not_include Time.utc(2006,12,22)
361
+ @rs.should_not_include Time.utc(2006,12,25)
362
+ end
363
+
364
+ specify "should find the previous time from a dangerous time" do
365
+ @rs.find_previous(@danger).should == Time.utc(2006,12,16)
366
+ end
367
+
368
+ end
369
+
370
+ context "A bi-weekly schedule with weekdays and a noon time" do
371
+ setup do
372
+ @rs = Recurring::Schedule.new :unit => 'weeks', :weekdays => %w{sat sunday}, :times => '12pm', :frequency => 2, :anchor => Time.utc(2001)
373
+ @danger = Time.utc(2006,12,17,18)
374
+ end
375
+
376
+ specify "should include noons of every other weekend" do
377
+ @rs.should_include Time.utc(2006,12,10,12)
378
+ @rs.should_include Time.utc(2006,12,16,12)
379
+ end
380
+
381
+ specify "should not include other midnights" do
382
+ @rs.should_not_include Time.utc(2006,12,22,12)
383
+ @rs.should_not_include Time.utc(2006,12,25,12)
384
+ end
385
+
386
+ specify "should find the previous time from a dangerous time" do
387
+ @rs.find_previous(@danger).should == Time.utc(2006,12,16,12)
388
+ end
389
+ end
390
+
323
391
  context "A weekly schedule with weekday params" do
324
392
 
325
393
  setup do
@@ -406,6 +474,11 @@ context "A third-weekly schedule with weekday and times params" do
406
474
  @rs.find_next(Time.utc(2006,12,4)).should == Time.utc(2006,12,18,15)
407
475
  @rs.find_next(Time.utc(2006,12,18)).should == Time.utc(2006,12,18,15)
408
476
  end
477
+
478
+ specify "should find the previous date" do
479
+ @rs.find_previous(Time.utc(2006,12,4)).should == Time.utc(2006,12,2,15)
480
+ @rs.find_previous(Time.utc(2006,12,18,20)).should == Time.utc(2006,12,18,15)
481
+ end
409
482
 
410
483
  end
411
484
 
@@ -574,7 +647,11 @@ context "An hourly schedule with an anchor" do
574
647
 
575
648
  specify "should not include any times with different sub hour parts" do
576
649
  end
577
-
650
+
651
+ specify "should find in range" do
652
+ @rs.find_in_range(Time.utc(2006), Time.utc(2007)).length.should == 24*365
653
+ end
654
+
578
655
  end
579
656
 
580
657
  context "An bi-hourly schedule with time params" do
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: recurring
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.3.2
7
- date: 2006-12-14 00:00:00 -08:00
6
+ version: 0.3.10
7
+ date: 2006-12-18 00:00:00 -08:00
8
8
  summary: A scheduling library for recurring events
9
9
  require_paths:
10
10
  - lib