runt 0.3.0 → 0.5.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,110 +1,219 @@
1
- #!/usr/bin/env ruby
2
-
3
- # :title:Runt -- Ruby Temporal Expressions
4
- #
5
- # == Runt -- Ruby Temporal Expressions
6
- #
7
- # The usage and design patterns expressed in this library are mostly...*uhm*..
8
- # <em>entirely</em>..*cough*...based on a series of
9
- # <tt>articles</tt>[http://www.martinfowler.com] by Martin Fowler.
10
- #
11
- # It highly recommended that anyone using Runt (or writing
12
- # object-oriented software :) take a moment to peruse the wealth of useful info
13
- # that Fowler has made publicly available:
14
- #
15
- # * An excellent introductory summation of temporal <tt>patterns</tt>[http://martinfowler.com/ap2/timeNarrative.html]
16
- # * Recurring event <tt>pattern</tt>[http://martinfowler.com/apsupp/recurring.pdf]
17
- #
18
- # Also, for those of you (like me, for example) still chained in your cubicle and forced
19
- # to write <tt>Java</tt>[http://java.sun.com] code, check out the original version of
20
- # project called <tt>ChronicJ</tt>[http://chronicj.org].
21
- #
22
- # ---
23
- # Author:: Matthew Lipper (mailto:info@digitalclash.com)
24
- # Copyright:: Copyright (c) 2004 Digital Clash, LLC
25
- # License:: See LICENSE.txt
26
- #
27
- # = Warranty
28
- #
29
- # This software is provided "as is" and without any express or
30
- # implied warranties, including, without limitation, the implied
31
- # warranties of merchantibility and fitness for a particular
32
- # purpose.
33
-
34
- require 'date'
35
- require 'date/format'
36
- require "runt/dprecision"
37
- require "runt/pdate"
38
- require "runt/temporalexpression"
39
- require "runt/schedule"
40
- require "runt/daterange"
41
-
42
- #
43
- # The Runt module is the main namespace for all Runt modules and classes. Using
44
- # require statements, it makes the entire Runt library available.It also
45
- # defines some new constants and exposes some already defined in the standard
46
- # library classes <tt>Date</tt> and <tt>DateTime</tt>.
47
- #
48
- # <b>See also</b> date.rb
49
- #
50
- module Runt
51
-
52
- #Yes it's true, I'm a big idiot!
53
- Sunday = Date::DAYNAMES.index("Sunday")
54
- Monday = Date::DAYNAMES.index("Monday")
55
- Tuesday = Date::DAYNAMES.index("Tuesday")
56
- Wednesday = Date::DAYNAMES.index("Wednesday")
57
- Thursday = Date::DAYNAMES.index("Thursday")
58
- Friday = Date::DAYNAMES.index("Friday")
59
- Saturday = Date::DAYNAMES.index("Saturday")
60
- Sun = Date::ABBR_DAYNAMES.index("Sun")
61
- Mon = Date::ABBR_DAYNAMES.index("Mon")
62
- Tue = Date::ABBR_DAYNAMES.index("Tue")
63
- Wed = Date::ABBR_DAYNAMES.index("Wed")
64
- Thu = Date::ABBR_DAYNAMES.index("Thu")
65
- Fri = Date::ABBR_DAYNAMES.index("Fri")
66
- Sat = Date::ABBR_DAYNAMES.index("Sat")
67
- First = 1
68
- Second = 2
69
- Third = 3
70
- Fourth = 4
71
- Fifth = 5
72
- Sixth = 6
73
- Seventh = 7
74
- Eigth = 8
75
- Ninth = 9
76
- Tenth = 10
77
-
78
- private
79
- class ApplyLast #:nodoc:
80
- def initialize()
81
- @negate=Proc.new{|n| n*-1}
82
- end
83
- def [](arg)
84
- @negate.call(arg)
85
- end
86
- end
87
- LastProc = ApplyLast.new
88
-
89
- public
90
- Last = LastProc[First]
91
- Last_of = LastProc[First]
92
- Second_to_last = LastProc[Second]
93
-
94
- end
95
-
96
- #
97
- # Add precision +Runt::DPrecision+ to standard library classes Date and DateTime
98
- # (which is a subclass of Date).
99
- #
100
- class Date
101
-
102
- include Runt::DPrecision
103
-
104
- attr_accessor :date_precision
105
-
106
- def date_precision
107
- return @date_precision unless @date_precision.nil?
108
- return Runt::DPrecision::DEFAULT
109
- end
110
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ # :title:Runt -- Ruby Temporal Expressions
4
+ #
5
+ # == Runt -- Ruby Temporal Expressions
6
+ #
7
+ # The usage and design patterns expressed in this library are mostly...*uhm*..
8
+ # <em>entirely</em>..*cough*...based on a series of
9
+ # <tt>articles</tt>[http://www.martinfowler.com] by Martin Fowler.
10
+ #
11
+ # It highly recommended that anyone using Runt (or writing
12
+ # object-oriented software :) take a moment to peruse the wealth of useful info
13
+ # that Fowler has made publicly available:
14
+ #
15
+ # * An excellent introductory summation of temporal <tt>patterns</tt>[http://martinfowler.com/ap2/timeNarrative.html]
16
+ # * Recurring event <tt>pattern</tt>[http://martinfowler.com/apsupp/recurring.pdf]
17
+ #
18
+ # Also, for those of you (like me, for example) still chained in your cubicle and forced
19
+ # to write <tt>Java</tt>[http://java.sun.com] code, check out the original version of
20
+ # project called <tt>ChronicJ</tt>[http://chronicj.org].
21
+ #
22
+ # ---
23
+ # Author:: Matthew Lipper (mailto:mlipper@gmail.com)
24
+ # Copyright:: Copyright (c) 2004 Digital Clash, LLC
25
+ # License:: See LICENSE.txt
26
+ #
27
+ # = Warranty
28
+ #
29
+ # This software is provided "as is" and without any express or
30
+ # implied warranties, including, without limitation, the implied
31
+ # warranties of merchantibility and fitness for a particular
32
+ # purpose.
33
+
34
+ require 'time'
35
+ require 'date'
36
+ require 'date/format'
37
+ require "runt/dprecision"
38
+ require "runt/pdate"
39
+ require "runt/temporalexpression"
40
+ require "runt/schedule"
41
+ require "runt/daterange"
42
+
43
+ #
44
+ # The Runt module is the main namespace for all Runt modules and classes. Using
45
+ # require statements, it makes the entire Runt library available.It also
46
+ # defines some new constants and exposes some already defined in the standard
47
+ # library classes <tt>Date</tt> and <tt>DateTime</tt>.
48
+ #
49
+ # <b>See also</b> date.rb
50
+ #
51
+ module Runt
52
+
53
+ class << self
54
+
55
+ def day_name(number)
56
+ Date::DAYNAMES[number]
57
+ end
58
+
59
+ def month_name(number)
60
+ Date::MONTHNAMES[number]
61
+ end
62
+
63
+ def format_time(date)
64
+ date.strftime('%I:%M%p')
65
+ end
66
+
67
+ def format_date(date)
68
+ date.ctime
69
+ end
70
+
71
+ #
72
+ # Cut and pasted from activesupport-1.2.5/lib/inflector.rb
73
+ #
74
+ def ordinalize(number)
75
+ if (number.to_i==-1)
76
+ 'last'
77
+ elsif (number.to_i==-2)
78
+ 'second to last'
79
+ elsif (11..13).include?(number.to_i % 100)
80
+ "#{number}th"
81
+ else
82
+ case number.to_i % 10
83
+ when 1: "#{number}st"
84
+ when 2: "#{number}nd"
85
+ when 3: "#{number}rd"
86
+ else "#{number}th"
87
+ end
88
+ end
89
+ end
90
+
91
+ end
92
+
93
+ #Yes it's true, I'm a big idiot!
94
+ Sunday = Date::DAYNAMES.index("Sunday")
95
+ Monday = Date::DAYNAMES.index("Monday")
96
+ Tuesday = Date::DAYNAMES.index("Tuesday")
97
+ Wednesday = Date::DAYNAMES.index("Wednesday")
98
+ Thursday = Date::DAYNAMES.index("Thursday")
99
+ Friday = Date::DAYNAMES.index("Friday")
100
+ Saturday = Date::DAYNAMES.index("Saturday")
101
+ Sun = Date::ABBR_DAYNAMES.index("Sun")
102
+ Mon = Date::ABBR_DAYNAMES.index("Mon")
103
+ Tue = Date::ABBR_DAYNAMES.index("Tue")
104
+ Wed = Date::ABBR_DAYNAMES.index("Wed")
105
+ Thu = Date::ABBR_DAYNAMES.index("Thu")
106
+ Fri = Date::ABBR_DAYNAMES.index("Fri")
107
+ Sat = Date::ABBR_DAYNAMES.index("Sat")
108
+ First = 1
109
+ Second = 2
110
+ Third = 3
111
+ Fourth = 4
112
+ Fifth = 5
113
+ Sixth = 6
114
+ Seventh = 7
115
+ Eigth = 8
116
+ Ninth = 9
117
+ Tenth = 10
118
+
119
+ private
120
+ class ApplyLast #:nodoc:
121
+ def initialize
122
+ @negate=Proc.new{|n| n*-1}
123
+ end
124
+ def [](arg)
125
+ @negate.call(arg)
126
+ end
127
+ end
128
+ LastProc = ApplyLast.new
129
+
130
+ public
131
+ Last = LastProc[First]
132
+ Last_of = LastProc[First]
133
+ Second_to_last = LastProc[Second]
134
+
135
+ end
136
+
137
+ #
138
+ # Add precision +Runt::DPrecision+ to standard library classes Date and DateTime
139
+ # (which is a subclass of Date). Also, add an inlcude? method for interoperability
140
+ # with +Runt::TExpr+ classes
141
+ #
142
+ class Date
143
+
144
+ include Runt
145
+
146
+ attr_accessor :date_precision
147
+
148
+ def include?(expr)
149
+ eql?(expr)
150
+ end
151
+
152
+ def date_precision
153
+ return @date_precision unless @date_precision.nil?
154
+ return Runt::DPrecision::DEFAULT
155
+ end
156
+ end
157
+
158
+ #
159
+ # Add the ability to use Time class
160
+ #
161
+ # Contributed by Paul Wright
162
+ #
163
+ class Time
164
+
165
+ include Runt
166
+
167
+ attr_accessor :date_precision
168
+ alias_method :old_initialize, :initialize
169
+ def initialize(*args)
170
+ if(args[0].instance_of?(Runt::DPrecision::Precision))
171
+ @precision=args.shift
172
+ else
173
+ @precision=Runt::DPrecision::DEFAULT
174
+ end
175
+ old_initialize(*args)
176
+ end
177
+
178
+ class << self
179
+ alias_method :old_parse, :parse
180
+ def parse(*args)
181
+ precision=Runt::DPrecision::DEFAULT
182
+ if(args[0].instance_of?(Runt::DPrecision::Precision))
183
+ precision=args.shift
184
+ end
185
+ _parse=old_parse(*args)
186
+ _parse.date_precision=precision
187
+ _parse
188
+ end
189
+ end
190
+
191
+ def date_precision
192
+ return @date_precision unless @date_precision.nil?
193
+ return Runt::DPrecision::DEFAULT
194
+ end
195
+ end
196
+
197
+ #
198
+ # Useful shortcuts!
199
+ #
200
+ # Contributed by Ara T. Howard who is pretty sure he got the idea from
201
+ # somewhere else. :-)
202
+ #
203
+ class Numeric #:nodoc:
204
+ def microseconds() Float(self * (10 ** -6)) end
205
+ def milliseconds() Float(self * (10 ** -3)) end
206
+ def seconds() self end
207
+ def minutes() 60 * seconds end
208
+ def hours() 60 * minutes end
209
+ def days() 24 * hours end
210
+ def weeks() 7 * days end
211
+ def months() 30 * days end
212
+ def years() 365 * days end
213
+ def decades() 10 * years end
214
+ # This causes RDoc to hurl:
215
+ %w[
216
+ microseconds milliseconds seconds minutes hours days weeks months years decades
217
+ ].each{|m| alias_method m.chop, m}
218
+ end
219
+
@@ -1,74 +1,74 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'date'
4
- require 'runt'
5
-
6
-
7
- module Runt
8
- # :title:DateRange
9
- # == DateRange
10
- #
11
- #
12
- # Based the <tt>range</tt>[http://martinfowler.com/ap2/range.html] pattern by Martin Fowler.
13
- #
14
- #
15
- #
16
- # Author:: Matthew Lipper
17
- class DateRange < Range
18
-
19
- include DPrecision
20
-
21
- attr_reader :start_expr, :end_expr
22
-
23
- def initialize(start_expr, end_expr,exclusive=false)
24
- super(start_expr, end_expr,exclusive)
25
- @start_expr, @end_expr = start_expr, end_expr
26
- end
27
-
28
- def include?(obj)
29
- return super(obj.min) && super(obj.max) if obj.kind_of? Range
30
- return super(obj)
31
- end
32
-
33
- def overlap?(obj)
34
- return true if( member?(obj) || include?(obj.min) || include?(obj.max) )
35
- return true if( obj.kind_of?(Range) && obj.include?(self) )
36
- false
37
- end
38
-
39
- def empty?
40
- return @start_expr>@end_expr
41
- end
42
-
43
- def gap(obj)
44
-
45
- return EMPTY if self.overlap? obj
46
-
47
- lower=nil
48
- higher=nil
49
-
50
- if((self<=>obj)<0)
51
- lower=self
52
- higher=obj
53
- else
54
- lower=obj
55
- higher=self
56
- end
57
-
58
- return DateRange.new((lower.end_expr+1),(higher.start_expr-1))
59
- end
60
-
61
- def <=>(other)
62
- return @start_expr <=> other.start_expr if(@start_expr != other.start_expr)
63
- return @end_expr <=> other.end_expr
64
- end
65
-
66
- def min; @start_expr end
67
- def max; @end_expr end
68
- def to_s; @start_expr.to_s + " " + @end_expr.to_s end
69
-
70
-
71
- EMPTY = DateRange.new(PDate.day(2004,2,2),PDate.day(2004,2,1))
72
-
73
- end
74
- end
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'date'
4
+ require 'runt'
5
+
6
+
7
+ module Runt
8
+ # :title:DateRange
9
+ # == DateRange
10
+ #
11
+ #
12
+ # Based the <tt>range</tt>[http://martinfowler.com/ap2/range.html] pattern by Martin Fowler.
13
+ #
14
+ #
15
+ #
16
+ # Author:: Matthew Lipper
17
+ class DateRange < Range
18
+
19
+ include DPrecision
20
+
21
+ attr_reader :start_expr, :end_expr
22
+
23
+ def initialize(start_expr, end_expr,exclusive=false)
24
+ super(start_expr, end_expr,exclusive)
25
+ @start_expr, @end_expr = start_expr, end_expr
26
+ end
27
+
28
+ def include?(obj)
29
+ return super(obj.min) && super(obj.max) if obj.kind_of? Range
30
+ return super(obj)
31
+ end
32
+
33
+ def overlap?(obj)
34
+ return true if( member?(obj) || include?(obj.min) || include?(obj.max) )
35
+ return true if( obj.kind_of?(Range) && obj.include?(self) )
36
+ false
37
+ end
38
+
39
+ def empty?
40
+ return @start_expr>@end_expr
41
+ end
42
+
43
+ def gap(obj)
44
+
45
+ return EMPTY if self.overlap? obj
46
+
47
+ lower=nil
48
+ higher=nil
49
+
50
+ if((self<=>obj)<0)
51
+ lower=self
52
+ higher=obj
53
+ else
54
+ lower=obj
55
+ higher=self
56
+ end
57
+
58
+ return DateRange.new((lower.end_expr+1),(higher.start_expr-1))
59
+ end
60
+
61
+ def <=>(other)
62
+ return @start_expr <=> other.start_expr if(@start_expr != other.start_expr)
63
+ return @end_expr <=> other.end_expr
64
+ end
65
+
66
+ def min; @start_expr end
67
+ def max; @end_expr end
68
+ def to_s; @start_expr.to_s + " " + @end_expr.to_s end
69
+
70
+
71
+ EMPTY = DateRange.new(PDate.day(2004,2,2),PDate.day(2004,2,1))
72
+
73
+ end
74
+ end