runt 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,153 +1,165 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'date'
4
- require 'runt'
5
-
6
-
7
- module Runt
8
-
9
-
10
- # :title:PDate
11
- # == PDate
12
- # Date and DateTime with explicit precision.
13
- #
14
- # Based the <tt>pattern</tt>[http://martinfowler.com/ap2/timePoint.html] by Martin Fowler.
15
- #
16
- #
17
- # Author:: Matthew Lipper
18
- class PDate < DateTime
19
- include DPrecision
20
-
21
- attr_accessor :date_precision
22
-
23
- class << self
24
- alias_method :old_civil, :civil
25
-
26
- def civil(*args)
27
- precision=nil
28
- if(args[0].instance_of?(DPrecision::Precision))
29
- precision = args.shift
30
- else
31
- return PDate::sec(*args)
32
- end
33
- _civil = old_civil(*args)
34
- _civil.date_precision = precision
35
- _civil
36
- end
37
- end
38
-
39
- class << self; alias_method :new, :civil end
40
-
41
- def include?(expr)
42
- eql?(expr)
43
- end
44
-
45
- def + (n)
46
- raise TypeError, 'expected numeric' unless n.kind_of?(Numeric)
47
- case @date_precision
48
- when YEAR then
49
- return DPrecision::to_p(PDate::civil(year+n,month,day),@date_precision)
50
- when MONTH then
51
- current_date = self.class.to_date(self)
52
- return DPrecision::to_p((current_date>>n),@date_precision)
53
- when DAY then
54
- return new_self_plus(n)
55
- when HOUR then
56
- return new_self_plus(n){ |n| n = (n*(1.to_r/24) ) }
57
- when MIN then
58
- return new_self_plus(n){ |n| n = (n*(1.to_r/1440) ) }
59
- when SEC then
60
- return new_self_plus(n){ |n| n = (n*(1.to_r/86400) ) }
61
- when MILLI then
62
- return self
63
- end
64
- end
65
-
66
- def - (x)
67
- case x
68
- when Numeric then
69
- return self+(-x)
70
- #FIXME!!
71
- when Date; return @ajd - x.ajd
72
- end
73
- raise TypeError, 'expected numeric or date'
74
- end
75
-
76
- def <=> (other)
77
- result = nil
78
- if(other.respond_to?("date_precision") && other.date_precision>@date_precision)
79
- result = super(DPrecision::to_p(other,@date_precision))
80
- else
81
- result = super(other)
82
- end
83
- #puts "#{self.to_s}<=>#{other.to_s} => #{result}" if $DEBUG
84
- result
85
- end
86
-
87
- def new_self_plus(n)
88
- if(block_given?)
89
- n=yield(n)
90
- end
91
- return DPrecision::to_p(self.class.new0(@ajd + n, @of, @sg),@date_precision)
92
- end
93
-
94
- def PDate.to_date(pdate)
95
- if( pdate.date_precision > DPrecision::DAY) then
96
- DateTime.new(pdate.year,pdate.month,pdate.day,pdate.hour,pdate.min,pdate.sec)
97
- end
98
- return Date.new(pdate.year,pdate.month,pdate.day)
99
- end
100
-
101
- def PDate.year(yr,*ignored)
102
- PDate.civil(YEAR, yr, MONTH.min_value, DAY.min_value )
103
- end
104
-
105
- def PDate.month( yr,mon,*ignored )
106
- PDate.civil(MONTH, yr, mon, DAY.min_value )
107
- end
108
-
109
- def PDate.day( yr,mon,day,*ignored )
110
- PDate.civil(DAY, yr, mon, day )
111
- end
112
-
113
- def PDate.hour( yr,mon,day,hr=HOUR.min_value,*ignored )
114
- PDate.civil(HOUR, yr, mon, day,hr,MIN.min_value, SEC.min_value)
115
- end
116
-
117
- def PDate.min( yr,mon,day,hr=HOUR.min_value,min=MIN.min_value,*ignored )
118
- PDate.civil(MIN, yr, mon, day,hr,min, SEC.min_value)
119
- end
120
-
121
- def PDate.sec( yr,mon,day,hr=HOUR.min_value,min=MIN.min_value,sec=SEC.min_value,*ignored )
122
- PDate.civil(SEC, yr, mon, day,hr,min, sec)
123
- end
124
-
125
- def PDate.millisecond( yr,mon,day,hr,min,sec,ms,*ignored )
126
- PDate.civil(SEC, yr, mon, day,hr,min, sec, ms, *ignored)
127
- #raise "Not implemented yet."
128
- end
129
-
130
- def PDate.default(*args)
131
- PDate.civil(DEFAULT, *args)
132
- end
133
-
134
- #
135
- # Custom dump which preserves DatePrecision
136
- #
137
- # Author:: Jodi Showers
138
- #
139
- def marshal_dump
140
- [date_precision, ajd, sg, of]
141
- end
142
-
143
- #
144
- # Custom load which preserves DatePrecision
145
- #
146
- # Author:: Jodi Showers
147
- #
148
- def marshal_load(dumped_obj)
149
- @date_precision, @ajd, @sg, @of=dumped_obj
150
- end
151
-
152
- end
153
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'date'
4
+ require 'runt'
5
+
6
+
7
+ module Runt
8
+
9
+
10
+ # :title:PDate
11
+ # == PDate
12
+ # Date and DateTime with explicit precision.
13
+ #
14
+ # Based the <tt>pattern</tt>[http://martinfowler.com/ap2/timePoint.html] by Martin Fowler.
15
+ #
16
+ #
17
+ # Author:: Matthew Lipper
18
+ class PDate < DateTime
19
+ include DPrecision
20
+
21
+ attr_accessor :date_precision
22
+
23
+ class << self
24
+ alias_method :old_civil, :civil
25
+
26
+ def civil(*args)
27
+ precision=nil
28
+ if(args[0].instance_of?(DPrecision::Precision))
29
+ precision = args.shift
30
+ else
31
+ return PDate::sec(*args)
32
+ end
33
+ _civil = old_civil(*args)
34
+ _civil.date_precision = precision
35
+ _civil
36
+ end
37
+ end
38
+
39
+ class << self; alias_method :new, :civil end
40
+
41
+ def include?(expr)
42
+ eql?(expr)
43
+ end
44
+
45
+ def + (n)
46
+ raise TypeError, 'expected numeric' unless n.kind_of?(Numeric)
47
+ case @date_precision
48
+ when YEAR then
49
+ return DPrecision::to_p(PDate::civil(year+n,month,day),@date_precision)
50
+ when MONTH then
51
+ current_date = self.class.to_date(self)
52
+ return DPrecision::to_p((current_date>>n),@date_precision)
53
+ when WEEK then
54
+ return new_self_plus(n*7)
55
+ when DAY then
56
+ return new_self_plus(n)
57
+ when HOUR then
58
+ return new_self_plus(n){ |n| n = (n*(1.to_r/24) ) }
59
+ when MIN then
60
+ return new_self_plus(n){ |n| n = (n*(1.to_r/1440) ) }
61
+ when SEC then
62
+ return new_self_plus(n){ |n| n = (n*(1.to_r/86400) ) }
63
+ when MILLI then
64
+ return self
65
+ end
66
+ end
67
+
68
+ def - (x)
69
+ case x
70
+ when Numeric then
71
+ return self+(-x)
72
+ #FIXME!!
73
+ when Date; return @ajd - x.ajd
74
+ end
75
+ raise TypeError, 'expected numeric or date'
76
+ end
77
+
78
+ def <=> (other)
79
+ result = nil
80
+ if(other.respond_to?("date_precision") && other.date_precision>@date_precision)
81
+ result = super(DPrecision::to_p(other,@date_precision))
82
+ else
83
+ result = super(other)
84
+ end
85
+ #puts "#{self.to_s}<=>#{other.to_s} => #{result}" if $DEBUG
86
+ result
87
+ end
88
+
89
+ def new_self_plus(n)
90
+ if(block_given?)
91
+ n=yield(n)
92
+ end
93
+ return DPrecision::to_p(self.class.new!(@ajd + n, @of, @sg),@date_precision)
94
+ end
95
+
96
+ def PDate.to_date(pdate)
97
+ if( pdate.date_precision > DPrecision::DAY) then
98
+ DateTime.new(pdate.year,pdate.month,pdate.day,pdate.hour,pdate.min,pdate.sec)
99
+ end
100
+ return Date.new(pdate.year,pdate.month,pdate.day)
101
+ end
102
+
103
+ def PDate.year(yr,*ignored)
104
+ PDate.civil(YEAR, yr, MONTH.min_value, DAY.min_value )
105
+ end
106
+
107
+ def PDate.month( yr,mon,*ignored )
108
+ PDate.civil(MONTH, yr, mon, DAY.min_value )
109
+ end
110
+
111
+ def PDate.week( yr,mon,day,*ignored )
112
+ #LJK: need to calculate which week this day implies,
113
+ #and then move the day back to the *first* day in that week;
114
+ #note that since rfc2445 defaults to weekstart=monday, I'm
115
+ #going to use commercial day-of-week
116
+ raw = PDate.day(yr, mon, day)
117
+ cooked = PDate.commercial(raw.cwyear, raw.cweek, 1)
118
+ PDate.civil(WEEK, cooked.year, cooked.month, cooked.day)
119
+ end
120
+
121
+ def PDate.day( yr,mon,day,*ignored )
122
+ PDate.civil(DAY, yr, mon, day )
123
+ end
124
+
125
+ def PDate.hour( yr,mon,day,hr=HOUR.min_value,*ignored )
126
+ PDate.civil(HOUR, yr, mon, day,hr,MIN.min_value, SEC.min_value)
127
+ end
128
+
129
+ def PDate.min( yr,mon,day,hr=HOUR.min_value,min=MIN.min_value,*ignored )
130
+ PDate.civil(MIN, yr, mon, day,hr,min, SEC.min_value)
131
+ end
132
+
133
+ def PDate.sec( yr,mon,day,hr=HOUR.min_value,min=MIN.min_value,sec=SEC.min_value,*ignored )
134
+ PDate.civil(SEC, yr, mon, day,hr,min, sec)
135
+ end
136
+
137
+ def PDate.millisecond( yr,mon,day,hr,min,sec,ms,*ignored )
138
+ PDate.civil(SEC, yr, mon, day,hr,min, sec, ms, *ignored)
139
+ #raise "Not implemented yet."
140
+ end
141
+
142
+ def PDate.default(*args)
143
+ PDate.civil(DEFAULT, *args)
144
+ end
145
+
146
+ #
147
+ # Custom dump which preserves DatePrecision
148
+ #
149
+ # Author:: Jodi Showers
150
+ #
151
+ def marshal_dump
152
+ [date_precision, ajd, start, offset]
153
+ end
154
+
155
+ #
156
+ # Custom load which preserves DatePrecision
157
+ #
158
+ # Author:: Jodi Showers
159
+ #
160
+ def marshal_load(dumped_obj)
161
+ @date_precision, @ajd, @sg, @of=dumped_obj
162
+ end
163
+
164
+ end
165
+ end
@@ -1,88 +1,88 @@
1
- #!/usr/bin/env ruby
2
-
3
- module Runt
4
-
5
-
6
- # Implementation of a <tt>pattern</tt>[http://martinfowler.com/apsupp/recurring.pdf]
7
- # for recurring calendar events created by Martin Fowler.
8
- class Schedule
9
-
10
- def initialize
11
- @elems = Hash.new
12
- self
13
- end
14
-
15
- # Schedule event to occur using the given expression.
16
- # NOTE: version 0.5.0 no longer uses an Array of ScheduleElements
17
- # internally to hold data. This would only matter to clients if they
18
- # they depended on the ability to call add multiple times for the same
19
- # event. Use the update method instead.
20
- def add(event, expression)
21
- @elems[event]=expression
22
- end
23
-
24
- # For the given date range, returns an Array of PDate objects at which
25
- # the supplied event is scheduled to occur.
26
- def dates(event, date_range)
27
- result=[]
28
- date_range.each do |date|
29
- result.push date if include?(event,date)
30
- end
31
- result
32
- end
33
-
34
- # Return true or false depend on if the supplied event is scheduled to occur on the
35
- # given date.
36
- def include?(event, date)
37
- return false unless @elems.include?(event)
38
- return 0<(self.select{|ev,xpr| ev.eql?(event)&&xpr.include?(date);}).size
39
- end
40
-
41
- #
42
- # Returns all Events whose Temporal Expression includes the given date/expression
43
- #
44
- def events(date)
45
- self.select{|ev,xpr| xpr.include?(date);}
46
- end
47
-
48
- #
49
- # Selects events using the user supplied block/Proc. The Proc must accept
50
- # two parameters: an Event and a TemporalExpression. It will be called
51
- # with each existing Event-expression pair at which point it can choose
52
- # to include the Event in the final result by returning true or to filter
53
- # it by returning false.
54
- #
55
- def select(&block)
56
- result=[]
57
- @elems.each_pair{|event,xpr| result.push(event) if block.call(event,xpr);}
58
- result
59
- end
60
-
61
- #
62
- # Call the supplied block/Proc with the currently configured
63
- # TemporalExpression associated with the supplied Event.
64
- #
65
- def update(event,&block)
66
- block.call(@elems[event])
67
- end
68
-
69
- end
70
-
71
- class Event
72
-
73
- attr_reader :id
74
-
75
- def initialize(id)
76
- raise Exception, "id argument cannot be nil" unless !id.nil?
77
- @id=id
78
- end
79
-
80
- def to_s; @id.to_s end
81
-
82
- def == (other)
83
- return true if other.kind_of?(Event) && @id==other.id
84
- end
85
-
86
- end
87
-
88
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ module Runt
4
+
5
+
6
+ # Implementation of a <tt>pattern</tt>[http://martinfowler.com/apsupp/recurring.pdf]
7
+ # for recurring calendar events created by Martin Fowler.
8
+ class Schedule
9
+
10
+ def initialize
11
+ @elems = Hash.new
12
+ self
13
+ end
14
+
15
+ # Schedule event to occur using the given expression.
16
+ # NOTE: version 0.5.0 no longer uses an Array of ScheduleElements
17
+ # internally to hold data. This would only matter to clients if they
18
+ # they depended on the ability to call add multiple times for the same
19
+ # event. Use the update method instead.
20
+ def add(event, expression)
21
+ @elems[event]=expression
22
+ end
23
+
24
+ # For the given date range, returns an Array of PDate objects at which
25
+ # the supplied event is scheduled to occur.
26
+ def dates(event, date_range)
27
+ result=[]
28
+ date_range.each do |date|
29
+ result.push date if include?(event,date)
30
+ end
31
+ result
32
+ end
33
+
34
+ # Return true or false depend on if the supplied event is scheduled to occur on the
35
+ # given date.
36
+ def include?(event, date)
37
+ return false unless @elems.include?(event)
38
+ return 0<(self.select{|ev,xpr| ev.eql?(event)&&xpr.include?(date);}).size
39
+ end
40
+
41
+ #
42
+ # Returns all Events whose Temporal Expression includes the given date/expression
43
+ #
44
+ def events(date)
45
+ self.select{|ev,xpr| xpr.include?(date);}
46
+ end
47
+
48
+ #
49
+ # Selects events using the user supplied block/Proc. The Proc must accept
50
+ # two parameters: an Event and a TemporalExpression. It will be called
51
+ # with each existing Event-expression pair at which point it can choose
52
+ # to include the Event in the final result by returning true or to filter
53
+ # it by returning false.
54
+ #
55
+ def select(&block)
56
+ result=[]
57
+ @elems.each_pair{|event,xpr| result.push(event) if block.call(event,xpr);}
58
+ result
59
+ end
60
+
61
+ #
62
+ # Call the supplied block/Proc with the currently configured
63
+ # TemporalExpression associated with the supplied Event.
64
+ #
65
+ def update(event,&block)
66
+ block.call(@elems[event])
67
+ end
68
+
69
+ end
70
+
71
+ class Event
72
+
73
+ attr_reader :id
74
+
75
+ def initialize(id)
76
+ raise Exception, "id argument cannot be nil" unless !id.nil?
77
+ @id=id
78
+ end
79
+
80
+ def to_s; @id.to_s end
81
+
82
+ def == (other)
83
+ return true if other.kind_of?(Event) && @id==other.id
84
+ end
85
+
86
+ end
87
+
88
+ end