timeframe 0.0.11 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document CHANGED
@@ -1,5 +1,5 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE CHANGED
@@ -1,20 +1,20 @@
1
- Copyright (c) 2009 Andy Rossmeissl
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2009 Andy Rossmeissl
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -10,6 +10,8 @@ http://rdoc.info/projects/rossmeissl/timeframe
10
10
 
11
11
  The good parts of Timeframe all came from the gentlemen at Fingertips[http://fngtps.com].
12
12
 
13
+ Thanks to @artemk for https://github.com/rossmeissl/timeframe/pull/5
14
+
13
15
  == Copyright
14
16
 
15
17
  Copyright (c) 2010 Andy Rossmeissl.
data/Rakefile CHANGED
@@ -6,26 +6,21 @@ end
6
6
  require 'bundler'
7
7
  Bundler::GemHelper.install_tasks
8
8
 
9
- require 'spec/rake/spectask'
10
- Spec::Rake::SpecTask.new(:spec) do |spec|
11
- spec.libs << 'lib' << 'spec'
12
- spec.spec_files = FileList['spec/**/*_spec.rb']
13
- end
9
+ require 'rake/testtask'
14
10
 
15
- Spec::Rake::SpecTask.new(:rcov) do |spec|
16
- spec.libs << 'lib' << 'spec'
17
- spec.pattern = 'spec/**/*_spec.rb'
18
- spec.rcov = true
11
+ Rake::TestTask.new do |t|
12
+ t.libs.push 'lib'
13
+ t.test_files = FileList['spec/**/*spec.rb']
14
+ t.verbose = true
19
15
  end
20
16
 
21
- task :default => :spec
22
17
 
23
- require 'rake/rdoctask'
24
- Rake::RDocTask.new do |rdoc|
25
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
18
+ task :default => :test
26
19
 
20
+ require 'rdoc/task'
21
+ RDoc::Task.new do |rdoc|
27
22
  rdoc.rdoc_dir = 'rdoc'
28
- rdoc.title = "timeframe #{version}"
23
+ rdoc.title = "timeframe"
29
24
  rdoc.rdoc_files.include('README*')
30
25
  rdoc.rdoc_files.include('lib/**/*.rb')
31
26
  end
data/lib/timeframe.rb CHANGED
@@ -1,16 +1,7 @@
1
1
  require 'date'
2
+ require 'multi_json'
2
3
  require 'active_support/version'
3
- %w{
4
- active_support/core_ext/hash
5
- active_support/core_ext/array/extract_options
6
- active_support/core_ext/string/conversions
7
- active_support/core_ext/date/conversions
8
- active_support/core_ext/integer/time
9
- active_support/core_ext/numeric/time
10
- active_support/json
11
- }.each do |active_support_3_requirement|
12
- require active_support_3_requirement
13
- end if ActiveSupport::VERSION::MAJOR == 3
4
+ require 'active_support/core_ext' if ActiveSupport::VERSION::MAJOR >= 3
14
5
 
15
6
  # Encapsulates a timeframe between two dates. The dates provided to the class are always until the last date. That means
16
7
  # that the last date is excluded.
@@ -20,7 +11,90 @@ end if ActiveSupport::VERSION::MAJOR == 3
20
11
  # # and holds 31 days
21
12
  # Timeframe.new(Date(2007,10,1), Date(2007,11,1)).days #=> 31
22
13
  class Timeframe
23
- attr_accessor :from, :to
14
+ class << self
15
+ # Shortcut method to return the Timeframe representing the current year (as defined by Time.now)
16
+ def this_year
17
+ new :year => Time.now.year
18
+ end
19
+
20
+ # Construct a new Timeframe, but constrain it by another
21
+ def constrained_new(start_date, end_date, constraint)
22
+ start_date, end_date = make_dates start_date, end_date
23
+ raise ArgumentError, 'Constraint must be a Timeframe' unless constraint.is_a? Timeframe
24
+ raise ArgumentError, "Start date #{start_date} should be earlier than end date #{end_date}" if start_date > end_date
25
+ if end_date <= constraint.start_date or start_date >= constraint.end_date
26
+ new constraint.start_date, constraint.start_date
27
+ elsif start_date.year == end_date.yesterday.year
28
+ new(start_date, end_date) & constraint
29
+ elsif start_date.year < constraint.start_date.year and constraint.start_date.year < end_date.yesterday.year
30
+ constraint
31
+ else
32
+ new [constraint.start_date, start_date].max, [constraint.end_date, end_date].min
33
+ end
34
+ end
35
+
36
+ # Create a timeframe +/- number of years around today
37
+ def mid(number)
38
+ start_date = Time.now.today - number.years
39
+ end_date = Time.now.today + number.years
40
+ new start_date, end_date
41
+ end
42
+
43
+ # Construct a new Timeframe by parsing an ISO 8601 time interval string
44
+ # http://en.wikipedia.org/wiki/ISO_8601#Time_intervals
45
+ def from_iso8601(str)
46
+ raise ArgumentError, 'Intervals should be specified according to ISO 8601, method 1, eliding times' unless str =~ /^\d\d\d\d-\d\d-\d\d\/\d\d\d\d-\d\d-\d\d$/
47
+ new *str.split('/')
48
+ end
49
+
50
+ # Construct a new Timeframe from a hash with keys startDate and endDate
51
+ def from_hash(hsh)
52
+ hsh = hsh.symbolize_keys
53
+ new hsh[:startDate], hsh[:endDate]
54
+ end
55
+
56
+ # Construct a new Timeframe from a year.
57
+ def from_year(year)
58
+ new :year => year.to_i
59
+ end
60
+
61
+ # Automagically parse a Timeframe from either a String or a Hash
62
+ def parse(input)
63
+ case input
64
+ when ::Integer
65
+ from_year input
66
+ when ::Hash
67
+ from_hash input
68
+ when ::String
69
+ str = input.strip
70
+ if str.start_with?('{')
71
+ from_hash ::MultiJson.decode(str)
72
+ elsif input =~ /\A\d\d\d\d\z/
73
+ from_year input
74
+ else
75
+ from_iso8601 str
76
+ end
77
+ else
78
+ raise ::ArgumentError, "Must be String or Hash"
79
+ end
80
+ end
81
+ alias :interval :parse
82
+ alias :from_json :parse
83
+
84
+ # Deprecated
85
+ def multiyear(*args) # :nodoc:
86
+ new *args
87
+ end
88
+
89
+ private
90
+
91
+ def make_dates(start_date, end_date)
92
+ [start_date.to_date, end_date.to_date]
93
+ end
94
+ end
95
+
96
+ attr_reader :start_date
97
+ attr_reader :end_date
24
98
 
25
99
  # Creates a new instance of Timeframe. You can either pass a start and end Date or a Hash with named arguments,
26
100
  # with the following options:
@@ -30,9 +104,6 @@ class Timeframe
30
104
  # <tt>:year</tt>: Start date becomes the first day of this year, and the end date becomes the first day of the
31
105
  # next year.
32
106
  #
33
- # By default, Timeframe.new will die if the resulting Timeframe would cross year boundaries. This can be overridden
34
- # by setting the <tt>:skip_year_boundary_crossing_check</tt> option.
35
- #
36
107
  # Examples:
37
108
  #
38
109
  # Timeframe.new Date.new(2007, 2, 1), Date.new(2007, 4, 1) # February and March
@@ -45,263 +116,182 @@ class Timeframe
45
116
  if month = options[:month]
46
117
  month = Date.parse(month).month if month.is_a? String
47
118
  year = options[:year] || Date.today.year
48
- from = Date.new(year, month, 1)
49
- to = from.next_month
119
+ start_date = Date.new(year, month, 1)
120
+ end_date = start_date.next_month
50
121
  elsif year = options[:year]
51
- from = Date.new(year, 1, 1)
52
- to = Date.new(year+1, 1, 1)
122
+ start_date = Date.new(year, 1, 1)
123
+ end_date = Date.new(year+1, 1, 1)
53
124
  end
54
125
 
55
- from = args.shift.to_date if from.nil? and args.any?
56
- to = args.shift.to_date if to.nil? and args.any?
126
+ start_date = args.shift.to_date if start_date.nil? and args.any?
127
+ end_date = args.shift.to_date if end_date.nil? and args.any?
57
128
 
58
- raise ArgumentError, "Please supply a start and end date, `#{args.map(&:inspect).to_sentence}' is not enough" if from.nil? or to.nil?
59
- raise ArgumentError, "Start date #{from} should be earlier than end date #{to}" if from > to
60
- raise ArgumentError, 'Timeframes that cross year boundaries are dangerous' unless options[:skip_year_boundary_crossing_check] or from.year == to.yesterday.year or from == to
129
+ raise ArgumentError, "Please supply a start and end date, `#{args.map(&:inspect).to_sentence}' is not enough" if start_date.nil? or end_date.nil?
130
+ raise ArgumentError, "Start date #{start_date} should be earlier than end date #{end_date}" if start_date > end_date
61
131
 
62
- @from, @to = from, to
132
+ @start_date, @end_date = start_date, end_date
63
133
  end
64
-
134
+
65
135
  def inspect # :nodoc:
66
- "<Timeframe(#{object_id}) #{days} days starting #{from} ending #{to}>"
136
+ "<Timeframe(#{object_id}) #{days} days starting #{start_date} ending #{end_date}>"
67
137
  end
68
-
138
+
69
139
  # The number of days in the timeframe
70
140
  #
71
141
  # Timeframe.new(Date.new(2007, 11, 1), Date.new(2007, 12, 1)).days #=> 30
72
142
  # Timeframe.new(:month => 1).days #=> 31
73
143
  # Timeframe.new(:year => 2004).days #=> 366
74
144
  def days
75
- (to - from).to_i
145
+ (end_date - start_date).to_i
76
146
  end
77
-
147
+
78
148
  # Returns true when a Date or other Timeframe is included in this Timeframe
79
149
  def include?(obj)
80
- # puts "checking to see if #{date} is between #{from} and #{to}" if Emitter::DEBUG
150
+ # puts "checking to see if #{date} is between #{start_date} and #{end_date}" if Emitter::DEBUG
81
151
  case obj
82
152
  when Date
83
- (from...to).include?(obj)
153
+ (start_date...end_date).include?(obj)
84
154
  when Time
85
- # (from...to).include?(obj.to_date)
155
+ # (start_date...end_date).include?(obj.to_date)
86
156
  raise "this wasn't previously supported, but it could be"
87
157
  when Timeframe
88
- from <= obj.from and to >= obj.to
158
+ start_date <= obj.start_date and end_date >= obj.end_date
89
159
  end
90
160
  end
91
-
161
+
92
162
  # Returns true when the parameter Timeframe is properly included in the Timeframe
93
163
  def proper_include?(other_timeframe)
94
164
  raise ArgumentError, 'Proper inclusion only makes sense when testing other Timeframes' unless other_timeframe.is_a? Timeframe
95
- (from < other_timeframe.from) and (to > other_timeframe.to)
165
+ (start_date < other_timeframe.start_date) and (end_date > other_timeframe.end_date)
96
166
  end
97
-
167
+
98
168
  # Returns true when this timeframe is equal to the other timeframe
99
169
  def ==(other)
100
170
  # puts "checking to see if #{self} is equal to #{other}" if Emitter::DEBUG
101
171
  return false unless other.is_a?(Timeframe)
102
- from == other.from and to == other.to
172
+ start_date == other.start_date and end_date == other.end_date
103
173
  end
104
174
  alias :eql? :==
105
-
175
+
106
176
  # Calculates a hash value for the Timeframe, used for equality checking and Hash lookups.
107
- #--
108
- # This needs to be an integer or else it won't use #eql?
109
177
  def hash
110
- from.hash + to.hash
111
- end
112
-
113
- # Returns an array of month-long subtimeframes
114
- #--
115
- # TODO: rename to month_subtimeframes
116
- def months
117
- raise ArgumentError, "Please only provide whole-month timeframes to Timeframe#months" unless from.day == 1 and to.day == 1
118
- raise ArgumentError, 'Timeframes that cross year boundaries are dangerous during Timeframe#months' unless from.year == to.yesterday.year
119
- year = from.year # therefore this only works in the from year
120
- (from.month..to.yesterday.month).map { |m| Timeframe.new :month => m, :year => year }
178
+ start_date.hash + end_date.hash
121
179
  end
122
-
180
+
123
181
  # Returns the relevant year as a Timeframe
124
182
  def year
125
- raise ArgumentError, 'Timeframes that cross year boundaries are dangerous during Timeframe#year' unless from.year == to.yesterday.year
126
- Timeframe.new :year => from.year
127
- end
128
-
129
- # Divides a Timeframe into component parts, each no more than a month long.
130
- #--
131
- # multiyear safe
132
- def month_subtimeframes
133
- (from.year..to.yesterday.year).map do |year|
134
- (1..12).map do |month|
135
- Timeframe.new(:year => year, :month => month) & self
136
- end
137
- end.flatten.compact
138
- end
139
-
140
- # Like #month_subtimeframes, but will discard partial months
141
- # multiyear safe
142
- def full_month_subtimeframes
143
- month_subtimeframes.map { |st| Timeframe.new(:year => st.from.year, :month => st.from.month) }
144
- end
145
-
146
- # Divides a Timeframe into component parts, each no more than a year long.
147
- #--
148
- # multiyear safe
149
- def year_subtimeframes
150
- (from.year..to.yesterday.year).map do |year|
151
- Timeframe.new(:year => year) & self
152
- end
183
+ raise ArgumentError, 'Timeframes that cross year boundaries are dangerous during Timeframe#year' unless start_date.year == end_date.yesterday.year
184
+ Timeframe.new :year => start_date.year
153
185
  end
154
-
155
- # Like #year_subtimeframes, but will discard partial years
156
- #--
157
- # multiyear safe
158
- def full_year_subtimeframes
159
- (from.year..to.yesterday.year).map do |year|
160
- Timeframe.new :year => year
186
+
187
+ # Returns an Array of month-long Timeframes. Partial months are **not** included by default.
188
+ # http://stackoverflow.com/questions/1724639/iterate-every-month-with-date-objects
189
+ def months
190
+ memo = []
191
+ ptr = start_date
192
+ while ptr <= end_date do
193
+ memo.push(Timeframe.new(:year => ptr.year, :month => ptr.month) & self)
194
+ ptr = ptr >> 1
161
195
  end
196
+ memo.flatten.compact
162
197
  end
163
-
198
+
164
199
  # Crop a Timeframe to end no later than the provided date.
165
- #--
166
- # multiyear safe
167
200
  def ending_no_later_than(date)
168
- if to < date
201
+ if end_date < date
169
202
  self
170
- elsif from >= date
203
+ elsif start_date >= date
171
204
  nil
172
205
  else
173
- Timeframe.multiyear from, date
206
+ Timeframe.new start_date, date
174
207
  end
175
208
  end
176
-
209
+
177
210
  # Returns a timeframe representing the intersection of the given timeframes
178
211
  def &(other_timeframe)
179
212
  this_timeframe = self
180
213
  if other_timeframe == this_timeframe
181
214
  this_timeframe
182
- elsif this_timeframe.from > other_timeframe.from and this_timeframe.to < other_timeframe.to
215
+ elsif this_timeframe.start_date > other_timeframe.start_date and this_timeframe.end_date < other_timeframe.end_date
183
216
  this_timeframe
184
- elsif other_timeframe.from > this_timeframe.from and other_timeframe.to < this_timeframe.to
217
+ elsif other_timeframe.start_date > this_timeframe.start_date and other_timeframe.end_date < this_timeframe.end_date
185
218
  other_timeframe
186
- elsif this_timeframe.from >= other_timeframe.to or this_timeframe.to <= other_timeframe.from
219
+ elsif this_timeframe.start_date >= other_timeframe.end_date or this_timeframe.end_date <= other_timeframe.start_date
187
220
  nil
188
221
  else
189
- Timeframe.new [this_timeframe.from, other_timeframe.from].max, [this_timeframe.to, other_timeframe.to].min, :skip_year_boundary_crossing_check => true
222
+ Timeframe.new [this_timeframe.start_date, other_timeframe.start_date].max, [this_timeframe.end_date, other_timeframe.end_date].min
190
223
  end
191
224
  end
192
-
225
+
193
226
  # Returns the fraction (as a Float) of another Timeframe that this Timeframe represents
194
227
  def /(other_timeframe)
195
228
  raise ArgumentError, 'You can only divide a Timeframe by another Timeframe' unless other_timeframe.is_a? Timeframe
196
229
  self.days.to_f / other_timeframe.days.to_f
197
230
  end
198
-
231
+
199
232
  # Crop a Timeframe by another Timeframe
200
233
  def crop(container)
201
234
  raise ArgumentError, 'You can only crop a timeframe by another timeframe' unless container.is_a? Timeframe
202
- self.class.new [from, container.from].max, [to, container.to].min
235
+ self.class.new [start_date, container.start_date].max, [end_date, container.end_date].min
203
236
  end
204
-
237
+
205
238
  # Returns an array of Timeframes representing the gaps left in the Timeframe after removing all given Timeframes
206
239
  def gaps_left_by(*timeframes)
207
240
  # remove extraneous timeframes
208
- timeframes.reject! { |t| t.to <= from }
209
- timeframes.reject! { |t| t.from >= to }
241
+ timeframes.reject! { |t| t.end_date <= start_date }
242
+ timeframes.reject! { |t| t.start_date >= end_date }
210
243
 
211
244
  # crop timeframes
212
245
  timeframes.map! { |t| t.crop self }
213
-
246
+
214
247
  # remove proper subtimeframes
215
248
  timeframes.reject! { |t| timeframes.detect { |u| u.proper_include? t } }
216
-
249
+
217
250
  # escape
218
251
  return [self] if timeframes.empty?
219
252
 
220
- timeframes.sort! { |x, y| x.from <=> y.from }
253
+ timeframes.sort! { |x, y| x.start_date <=> y.start_date }
221
254
 
222
- a = [ from ] + timeframes.collect(&:to)
223
- b = timeframes.collect(&:from) + [ to ]
255
+ a = [ start_date ] + timeframes.collect(&:end_date)
256
+ b = timeframes.collect(&:start_date) + [ end_date ]
224
257
 
225
258
  a.zip(b).map do |gap|
226
- Timeframe.new(*gap) if gap[1] > gap[0]
259
+ Timeframe.new(*gap, :skip_year_boundary_crossing_check => true) if gap[1] > gap[0]
227
260
  end.compact
228
261
  end
229
-
262
+
230
263
  # Returns true if the union of the given Timeframes includes the Timeframe
231
264
  def covered_by?(*timeframes)
232
265
  gaps_left_by(*timeframes).empty?
233
266
  end
234
-
267
+
235
268
  # Returns the same Timeframe, only a year earlier
236
269
  def last_year
237
- self.class.new((from - 1.year), (to - 1.year))
238
- end
239
-
240
- def as_json(*)
241
- to_param
270
+ self.class.new((start_date - 1.year), (end_date - 1.year))
242
271
  end
243
272
 
244
- # overriding this so that as_json is not used
245
273
  def to_json(*)
246
- to_param
274
+ %({"startDate":"#{start_date.iso8601}","endDate":"#{end_date.iso8601}"})
247
275
  end
248
276
 
277
+ def as_json(*)
278
+ { :startDate => start_date.iso8601, :endDate => end_date.iso8601 }
279
+ end
280
+
249
281
  # An ISO 8601 "time interval" like YYYY-MM-DD/YYYY-MM-DD
250
- def to_param
251
- "#{from}/#{to}"
282
+ def iso8601
283
+ "#{start_date.iso8601}/#{end_date.iso8601}"
252
284
  end
253
-
254
- # The String representation is equivalent to its ISO 8601 form
255
- def to_s
256
- to_param
285
+ alias :to_s :iso8601
286
+ alias :to_param :iso8601
287
+
288
+ # Deprecated
289
+ def from # :nodoc:
290
+ @start_date
257
291
  end
258
292
 
259
- class << self
260
- def make_dates(from, to) # :nodoc:
261
- return from.to_date, to.to_date
262
- end
263
-
264
- # Shortcut method to return the Timeframe representing the current year (as defined by Time.now)
265
- def this_year
266
- new :year => Time.now.year
267
- end
268
-
269
- # Construct a new Timeframe, but constrain it by another
270
- def constrained_new(from, to, constraint)
271
- from, to = make_dates from, to
272
- raise ArgumentError, 'Constraint must be a Timeframe' unless constraint.is_a? Timeframe
273
- raise ArgumentError, "Start date #{from} should be earlier than end date #{to}" if from > to
274
- if to <= constraint.from or from >= constraint.to
275
- new constraint.from, constraint.from
276
- elsif from.year == to.yesterday.year
277
- new(from, to) & constraint
278
- elsif from.year < constraint.from.year and constraint.from.year < to.yesterday.year
279
- constraint
280
- else
281
- new [constraint.from, from].max, [constraint.to, to].min
282
- end
283
- end
284
-
285
- # Shortcut for #new that automatically skips year boundary crossing checks
286
- def multiyear(from, to)
287
- from, to = make_dates from, to
288
- new from, to, :skip_year_boundary_crossing_check => true
289
- end
290
-
291
- # Create a multiyear timeframe +/- number of years around today
292
- def mid(number)
293
- from = Time.zone.today - number.years
294
- to = Time.zone.today + number.years
295
- multiyear from, to
296
- end
297
-
298
- # Construct a new Timeframe by parsing an ISO 8601 time interval string
299
- # http://en.wikipedia.org/wiki/ISO_8601#Time_intervals
300
- def interval(str)
301
- raise ArgumentError, 'Intervals should be specified as a string' unless str.is_a? String
302
- raise ArgumentError, 'Intervals should be specified according to ISO 8601, method 1, eliding times' unless str =~ /^\d\d\d\d-\d\d-\d\d\/\d\d\d\d-\d\d-\d\d$/
303
- multiyear *str.split('/')
304
- end
305
- alias :from_json :interval
293
+ # Deprecated
294
+ def to # :nodoc:
295
+ @end_date
306
296
  end
307
297
  end
@@ -0,0 +1,9 @@
1
+ class Array
2
+ # Constructs an array of timeframes representing the "gaps" left by the given array of timeframes.
3
+ #
4
+ # To use this feature, you must explicitly require 'timeframe/core_ext/array'
5
+ def multiple_timeframes_gaps_left_by(*time_frames)
6
+ raise ArgumentError.new 'You can only use timeframe for this operation' unless [self + time_frames].flatten.all?{|el| el.is_a?(Timeframe)}
7
+ self.inject([]){|a,b| a << b.gaps_left_by(*time_frames)}.flatten
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  class Timeframe
2
- VERSION = '0.0.11'
2
+ VERSION = '0.1.0'
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
3
  Bundler.setup
4
- require 'spec'
5
- require 'spec/autorun'
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
6
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
7
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
- require 'timeframe'
9
-
10
- Spec::Runner.configure do |config|
11
-
12
- end
8
+ require File.expand_path('../../lib/timeframe.rb', __FILE__)
9
+ require File.expand_path('../../lib/timeframe/core_ext/array.rb', __FILE__)
@@ -1,58 +1,52 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require File.expand_path('../spec_helper', __FILE__)
2
2
 
3
3
  describe Timeframe do
4
4
  describe 'initialization' do
5
5
  it 'should create a timeframe using date strings' do
6
6
  tf = Timeframe.new('2008-02-14', '2008-05-10')
7
- tf.from.should == Date.parse('2008-02-14')
8
- tf.to.should == Date.parse('2008-05-10')
7
+ tf.from.must_equal Date.parse('2008-02-14')
8
+ tf.to.must_equal Date.parse('2008-05-10')
9
9
  end
10
10
  it 'should create a timeframe using date objects' do
11
11
  start = Date.parse('2008-02-14')
12
12
  finish = Date.parse('2008-05-10')
13
13
  tf = Timeframe.new(start, finish)
14
- tf.from.should == start
15
- tf.to.should == finish
14
+ tf.from.must_equal start
15
+ tf.to.must_equal finish
16
16
  end
17
17
  it "should accept months" do
18
18
  timeframe = Timeframe.new(:month => 1)
19
- timeframe.from.should == Date.today.change(:month => 1, :day => 1)
20
- timeframe.to.should == Date.today.change(:month => 2, :day => 1)
19
+ timeframe.from.must_equal Date.today.change(:month => 1, :day => 1)
20
+ timeframe.to.must_equal Date.today.change(:month => 2, :day => 1)
21
21
  end
22
22
  it "should accept month names" do
23
23
  timeframe = Timeframe.new(:month => 'february')
24
- timeframe.from.should == Date.today.change(:month => 2, :day => 1)
25
- timeframe.to.should == Date.today.change(:month => 3, :day => 1)
24
+ timeframe.from.must_equal Date.today.change(:month => 2, :day => 1)
25
+ timeframe.to.must_equal Date.today.change(:month => 3, :day => 1)
26
26
  end
27
27
  it "should accept years" do
28
28
  timeframe = Timeframe.new(:year => 2004)
29
- timeframe.from.should == Date.new(2004, 1, 1)
30
- timeframe.to.should == Date.new(2005, 1, 1)
29
+ timeframe.from.must_equal Date.new(2004, 1, 1)
30
+ timeframe.to.must_equal Date.new(2005, 1, 1)
31
31
  end
32
32
  it "should accept years and months" do
33
33
  timeframe = Timeframe.new(:year => 2005, :month => 5)
34
- timeframe.from.should == Date.new(2005, 5, 1)
35
- timeframe.to.should == Date.new(2005, 6, 1)
34
+ timeframe.from.must_equal Date.new(2005, 5, 1)
35
+ timeframe.to.must_equal Date.new(2005, 6, 1)
36
36
  end
37
37
  it "should not accept just one date argument" do
38
38
  lambda {
39
39
  Timeframe.new Date.new(2007, 2, 1)
40
- }.should raise_error(ArgumentError, /supply/)
40
+ }.must_raise(ArgumentError, /supply/)
41
41
  end
42
42
  it "should not accept end date that is earlier than start date" do
43
43
  lambda {
44
44
  timeframe = Timeframe.new Date.new(2008, 1, 1), Date.new(2007, 1, 1)
45
- }.should raise_error(ArgumentError, /earlier/)
45
+ }.must_raise(ArgumentError, /earlier/)
46
46
  end
47
- it "should not accept timeframes that cross year boundaries" do
48
- lambda {
49
- timeframe = Timeframe.new Date.new(2007, 1, 1), Date.new(2008, 1, 2)
50
- }.should raise_error(ArgumentError, /cross/)
51
- end
52
- it "should optionally accept timeframes that cross year boundaries" do
53
- lambda {
54
- timeframe = Timeframe.new Date.new(2007, 1, 1), Date.new(2008, 1, 2), :skip_year_boundary_crossing_check => true
55
- }.should_not raise_error
47
+ it "should always accept timeframes that cross year boundaries" do
48
+ timeframe = Timeframe.new Date.new(2007, 1, 1), Date.new(2008, 1, 2)
49
+ timeframe.start_date.must_equal Date.new(2007, 1, 1)
56
50
  end
57
51
  end
58
52
 
@@ -61,7 +55,7 @@ describe Timeframe do
61
55
  start = Date.parse('2008-02-14')
62
56
  finish = Date.parse('2008-05-10')
63
57
  tf = Timeframe.new(start, finish)
64
- tf.inspect.should =~ /<Timeframe\(-?\d+\) 86 days starting 2008-02-14 ending 2008-05-10>/
58
+ tf.inspect.must_match %r{<Timeframe\(-?\d+\) 86 days starting 2008-02-14 ending 2008-05-10>}
65
59
  end
66
60
  end
67
61
 
@@ -76,60 +70,60 @@ describe Timeframe do
76
70
  constraint = Timeframe.new :year => 2008
77
71
  may = Timeframe.new Date.new(2008,5,1), Date.new(2008,6,1)
78
72
  january = Timeframe.new Date.new(2008,1,1), Date.new(2008,2,1)
79
- Timeframe.constrained_new(may.from, may.to, constraint).should == may
80
- Timeframe.constrained_new(Date.new(2007,1,1), Date.new(2010,1,1), constraint).should == constraint
81
- Timeframe.constrained_new(Date.new(2007,11,1), Date.new(2008,2,1), constraint).should == january
73
+ Timeframe.constrained_new(may.from, may.to, constraint).must_equal may
74
+ Timeframe.constrained_new(Date.new(2007,1,1), Date.new(2010,1,1), constraint).must_equal constraint
75
+ Timeframe.constrained_new(Date.new(2007,11,1), Date.new(2008,2,1), constraint).must_equal january
82
76
  end
83
77
  it 'should return a timeframe spanning start and end date if within constraint' do
84
78
  tf = Timeframe.constrained_new(start, finish, constraint)
85
- tf.from.should == start
86
- tf.to.should == finish
79
+ tf.from.must_equal start
80
+ tf.to.must_equal finish
87
81
  end
88
82
  it 'should return a timeframe spanning constraint start and end date if outside constraint' do
89
83
  constraint = Timeframe.new(start, finish)
90
84
  tf = Timeframe.constrained_new(constraint_start, constraint_finish, constraint)
91
- tf.from.should == start
92
- tf.to.should == finish
85
+ tf.from.must_equal start
86
+ tf.to.must_equal finish
93
87
  end
94
88
  it 'should return a timeframe starting at constraint start' do
95
89
  start = Date.parse('2008-01-01')
96
90
  constraint_start = Date.parse('2008-01-14')
97
91
  constraint = Timeframe.new(constraint_start, constraint_finish)
98
92
  tf = Timeframe.constrained_new(start, finish, constraint)
99
- tf.from.should == constraint_start
100
- tf.to.should == finish
93
+ tf.from.must_equal constraint_start
94
+ tf.to.must_equal finish
101
95
  end
102
96
  it 'should return a timeframe ending at constraint end' do
103
97
  constraint_finish = Date.parse('2008-04-14')
104
98
  constraint = Timeframe.new(constraint_start, constraint_finish)
105
99
  tf = Timeframe.constrained_new(start, finish, constraint)
106
- tf.from.should == start
107
- tf.to.should == constraint_finish
100
+ tf.from.must_equal start
101
+ tf.to.must_equal constraint_finish
108
102
  end
109
103
  it "should return a 0-length timeframe when constraining a timeframe by a disjoint timeframe" do
110
104
  constraint = Timeframe.new :year => 2010
111
105
  timeframe = Timeframe.constrained_new(
112
106
  Date.new(2009,1,1), Date.new(2010,1,1), constraint)
113
- timeframe.days.should == 0
107
+ timeframe.days.must_equal 0
114
108
  end
115
109
  end
116
110
 
117
111
  describe '.this_year' do
118
112
  it "should return the current year" do
119
- Timeframe.this_year.should == Timeframe.new(:year => Time.now.year)
113
+ Timeframe.this_year.must_equal Timeframe.new(:year => Time.now.year)
120
114
  end
121
115
  end
122
116
 
123
117
  describe '#days' do
124
118
  it "should return them number of days included" do
125
119
  #TODO: make these separate "it" blocks, per best practices
126
- Timeframe.new(Date.new(2007, 1, 1), Date.new(2008, 1, 1)).days.should == 365
127
- Timeframe.new(Date.new(2008, 1, 1), Date.new(2009, 1, 1)).days.should == 366 #leap year
128
- Timeframe.new(Date.new(2007, 11, 1), Date.new(2007, 12, 1)).days.should == 30
129
- Timeframe.new(Date.new(2007, 11, 1), Date.new(2008, 1, 1)).days.should == 61
130
- Timeframe.new(Date.new(2007, 2, 1), Date.new(2007, 3, 1)).days.should == 28
131
- Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 3, 1)).days.should == 29
132
- Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 2, 1)).days.should == 0
120
+ Timeframe.new(Date.new(2007, 1, 1), Date.new(2008, 1, 1)).days.must_equal 365
121
+ Timeframe.new(Date.new(2008, 1, 1), Date.new(2009, 1, 1)).days.must_equal 366 #leap year
122
+ Timeframe.new(Date.new(2007, 11, 1), Date.new(2007, 12, 1)).days.must_equal 30
123
+ Timeframe.new(Date.new(2007, 11, 1), Date.new(2008, 1, 1)).days.must_equal 61
124
+ Timeframe.new(Date.new(2007, 2, 1), Date.new(2007, 3, 1)).days.must_equal 28
125
+ Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 3, 1)).days.must_equal 29
126
+ Timeframe.new(Date.new(2008, 2, 1), Date.new(2008, 2, 1)).days.must_equal 0
133
127
  end
134
128
  end
135
129
 
@@ -142,69 +136,61 @@ describe Timeframe do
142
136
  Date.new(2008, 2, 5),
143
137
  Date.new(2008, 2, 29)
144
138
  ].each do |date|
145
- timeframe.include?(date).should == true
139
+ timeframe.include?(date).must_equal true
146
140
  end
147
141
  [
148
142
  Date.new(2008, 1, 1),
149
143
  Date.new(2007, 2, 1),
150
144
  Date.new(2008, 3, 1)
151
145
  ].each do |date|
152
- timeframe.include?(date).should == false
146
+ timeframe.include?(date).must_equal false
153
147
  end
154
148
  end
155
149
  end
156
150
 
157
151
  describe '#==' do
158
152
  it "should be able to know if it's equal to another Timeframe object" do
159
- Timeframe.new(:year => 2007).should == Timeframe.new(:year => 2007)
160
- Timeframe.new(:year => 2004, :month => 1).should == Timeframe.new(:year => 2004, :month => 1)
153
+ Timeframe.new(:year => 2007).must_equal Timeframe.new(:year => 2007)
154
+ Timeframe.new(:year => 2004, :month => 1).must_equal Timeframe.new(:year => 2004, :month => 1)
161
155
  end
162
-
156
+
163
157
  it "should hash equal hash values when the timeframe is equal" do
164
- Timeframe.new(:year => 2007).hash.should == Timeframe.new(:year => 2007).hash
165
- Timeframe.new(:year => 2004, :month => 1).hash.should == Timeframe.new(:year => 2004, :month => 1).hash
158
+ Timeframe.new(:year => 2007).hash.must_equal Timeframe.new(:year => 2007).hash
159
+ Timeframe.new(:year => 2004, :month => 1).hash.must_equal Timeframe.new(:year => 2004, :month => 1).hash
166
160
  end
167
161
  end
168
162
 
169
163
  describe '#months' do
170
164
  it "should return an array of month-long subtimeframes" do
171
- Timeframe.new(:year => 2009).months.length.should == 12
172
- end
173
- it "should not return an array of month-long subtimeframes if provided an inappropriate range" do
174
- lambda {
175
- Timeframe.new(Date.new(2009, 3, 2), Date.new(2009, 3, 5)).months
176
- }.should raise_error(ArgumentError, /whole/)
177
- lambda {
178
- Timeframe.new(Date.new(2009, 1, 1), Date.new(2012, 1, 1), :skip_year_boundary_crossing_check => true).months
179
- }.should raise_error(ArgumentError, /dangerous during/)
165
+ Timeframe.new(:year => 2009).months.length.must_equal 12
180
166
  end
181
167
  end
182
168
 
183
169
  describe '#year' do
184
170
  it "should return the relevant year of a timeframe" do
185
- Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 4, 1)).year.should == Timeframe.new(:year => 2009)
171
+ Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 4, 1)).year.must_equal Timeframe.new(:year => 2009)
186
172
  end
187
173
  it "should not return the relevant year of a timeframe if provided an inappropriate range" do
188
174
  lambda {
189
- Timeframe.new(Date.new(2009, 1, 1), Date.new(2012, 1, 1), :skip_year_boundary_crossing_check => true).year
190
- }.should raise_error(ArgumentError, /dangerous during/)
175
+ Timeframe.new(Date.new(2009, 1, 1), Date.new(2012, 1, 1)).year
176
+ }.must_raise(ArgumentError, /dangerous during/)
191
177
  end
192
178
  end
193
179
 
194
180
  describe '#&' do
195
181
  it "should return its intersection with another timeframe" do
196
182
  #TODO: make these separate "it" blocks, per best practices
197
- (Timeframe.new(:month => 4) & Timeframe.new(:month => 6)).should be_nil
198
- (Timeframe.new(:month => 4) & Timeframe.new(:month => 5)).should be_nil
199
- (Timeframe.new(:month => 4) & Timeframe.new(:month => 4)).should == Timeframe.new(:month => 4)
200
- (Timeframe.new(:year => Time.now.year) & Timeframe.new(:month => 4)).should == Timeframe.new(:month => 4)
201
- (Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 6, 1)) & Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 8, 1))).should == Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 6, 1))
183
+ (Timeframe.new(:month => 4) & Timeframe.new(:month => 6)).must_be_nil
184
+ (Timeframe.new(:month => 4) & Timeframe.new(:month => 5)).must_be_nil
185
+ (Timeframe.new(:month => 4) & Timeframe.new(:month => 4)).must_equal Timeframe.new(:month => 4)
186
+ (Timeframe.new(:year => Time.now.year) & Timeframe.new(:month => 4)).must_equal Timeframe.new(:month => 4)
187
+ (Timeframe.new(Date.new(2009, 2, 1), Date.new(2009, 6, 1)) & Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 8, 1))).must_equal Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 6, 1))
202
188
  end
203
189
  end
204
190
 
205
191
  describe '#/' do
206
192
  it "should return a fraction of another timeframe" do
207
- (Timeframe.new(:month => 4, :year => 2009) / Timeframe.new(:year => 2009)).should == (30.0 / 365.0)
193
+ (Timeframe.new(:month => 4, :year => 2009) / Timeframe.new(:year => 2009)).must_equal (30.0 / 365.0)
208
194
  end
209
195
  end
210
196
 
@@ -215,67 +201,96 @@ describe Timeframe do
215
201
  Timeframe.new(:year => 2009, :month => 5),
216
202
  Timeframe.new(Date.new(2009, 8, 1), Date.new(2009, 11, 1)),
217
203
  Timeframe.new(Date.new(2009, 9, 1), Date.new(2009, 10, 1))
218
- ).should ==
204
+ ).must_equal(
219
205
  [ Timeframe.new(Date.new(2009, 1, 1), Date.new(2009, 3, 1)),
220
206
  Timeframe.new(Date.new(2009, 4, 1), Date.new(2009, 5, 1)),
221
207
  Timeframe.new(Date.new(2009, 6, 1), Date.new(2009, 8, 1)),
222
- Timeframe.new(Date.new(2009, 11, 1), Date.new(2010, 1, 1)) ]
208
+ Timeframe.new(Date.new(2009, 11, 1), Date.new(2010, 1, 1)) ])
223
209
  end
224
210
  end
225
211
 
226
212
  describe '#covered_by?' do
227
213
  it "should be able to ascertain gaps left by a list of other Timeframes" do
228
214
  Timeframe.new(:year => 2009).covered_by?(
229
- Timeframe.new(:month => 1, :year => 2009),
215
+ Timeframe.new(:month => 1, :year => 2009),
230
216
  Timeframe.new(Date.new(2009, 2, 1), Date.new(2010, 1, 1))
231
- ).should be_true
217
+ ).must_equal(true)
232
218
  end
233
219
  end
234
220
 
235
221
  describe '#last_year' do
236
222
  it "should return its predecessor in a previous year" do
237
- Timeframe.this_year.last_year.should ==
238
- Timeframe.new(Date.new(Date.today.year - 1, 1, 1), Date.new(Date.today.year, 1, 1))
239
- end
240
- end
241
-
242
- describe 'Timeframe:class#interval' do
243
- it 'should parse ISO 8601 interval format' do
244
- Timeframe.interval('2009-01-01/2010-01-01').should == Timeframe.new(:year => 2009)
245
- end
246
- it 'should skip year boundary checking' do
247
- lambda {
248
- Timeframe.interval '2009-01-01/2011-01-01'
249
- }.should_not raise_error
250
- end
251
- it 'should understand its own #to_param' do
252
- t = Timeframe.new(:year => 2009)
253
- Timeframe.interval(t.to_param).should == t
223
+ Timeframe.this_year.last_year.must_equal Timeframe.new(Date.new(Date.today.year - 1, 1, 1), Date.new(Date.today.year, 1, 1))
254
224
  end
255
225
  end
256
226
 
257
- describe 'Timeframe:class#from_json' do
258
- it 'should understand its own #to_json' do
259
- t = Timeframe.new(:year => 2009)
260
- Timeframe.from_json(t.to_json).should == t
227
+ describe '.parse' do
228
+ it 'understands ISO8601' do
229
+ Timeframe.parse('2009-01-01/2010-01-01').must_equal Timeframe.new(:year => 2009)
230
+ end
231
+ it 'understands plain year' do
232
+ plain_year = 2009
233
+ Timeframe.parse(plain_year).must_equal Timeframe.new(:year => plain_year)
234
+ Timeframe.parse(plain_year.to_s).must_equal Timeframe.new(:year => plain_year)
235
+ end
236
+ it 'understands JSON' do
237
+ json =<<-EOS
238
+ {"startDate":"2009-05-01", "endDate":"2009-06-01"}
239
+ EOS
240
+ Timeframe.parse(json).must_equal Timeframe.new(:year => 2009, :month => 5)
241
+ end
242
+ it 'understands a Ruby hash' do
243
+ hsh = { :startDate => '2009-05-01', :endDate => '2009-06-01' }
244
+ Timeframe.parse(hsh).must_equal Timeframe.new(:year => 2009, :month => 5)
245
+ Timeframe.parse(hsh.stringify_keys).must_equal Timeframe.new(:year => 2009, :month => 5)
261
246
  end
262
247
  end
263
-
248
+
264
249
  describe '#to_json' do
265
250
  it 'should generate JSON (test fails on ruby 1.8)' do
266
- Timeframe.new(:year => 2009).to_json.should == "2009-01-01/2010-01-01"
251
+ Timeframe.new(:year => 2009).to_json.must_equal %({"startDate":"2009-01-01","endDate":"2010-01-01"})
252
+ end
253
+ it 'understands its own #to_json' do
254
+ t = Timeframe.new(:year => 2009, :month => 5)
255
+ Timeframe.from_json(t.to_json).must_equal t
267
256
  end
268
257
  end
269
-
258
+
270
259
  describe '#to_param' do
271
260
  it 'should generate a URL-friendly parameter' do
272
- Timeframe.new(:year => 2009).to_param.should == "2009-01-01/2010-01-01"
261
+ Timeframe.new(:year => 2009).to_param.must_equal "2009-01-01/2010-01-01"
262
+ end
263
+ it 'understands its own #to_param' do
264
+ t = Timeframe.new(:year => 2009, :month => 5)
265
+ Timeframe.parse(t.to_param).must_equal t
273
266
  end
274
267
  end
275
-
268
+
276
269
  describe '#to_s' do
277
270
  it 'should not only look at month numbers when describing multi-year timeframes' do
278
- Timeframe.multiyear(Date.parse('2008-01-01'), Date.parse('2010-01-01')).to_s.should == "2008-01-01/2010-01-01"
271
+ Timeframe.new(Date.parse('2008-01-01'), Date.parse('2010-01-01')).to_s.must_equal "2008-01-01/2010-01-01"
272
+ end
273
+ end
274
+
275
+ describe "Array#multiple_timeframes_gaps_left_by" do
276
+ it "should raise error if not a Timeframes are going to be merged" do
277
+ lambda {
278
+ [Timeframe.new(Date.parse('2011-10-10'), Date.parse('2011-10-28'))].multiple_timeframes_gaps_left_by(1,2)
279
+ }.must_raise(ArgumentError, /only use timeframe/)
280
+ end
281
+
282
+ it "should properly work with multiple timeframes" do
283
+ t1 = Timeframe.new(Date.parse('2011-10-10'), Date.parse('2011-10-28'))
284
+ t2 = Timeframe.new(Date.parse('2011-11-01'), Date.parse('2011-11-12'))
285
+
286
+ t3 = Timeframe.new(Date.parse('2011-10-11'), Date.parse('2011-10-15'))
287
+ t4 = Timeframe.new(Date.parse('2011-11-01'), Date.parse('2011-11-08'))
288
+
289
+ [t1, t2].multiple_timeframes_gaps_left_by(t3, t4).must_equal(
290
+ [ Timeframe.new(Date.parse('2011-10-10'), Date.parse('2011-10-11')),
291
+ Timeframe.new(Date.parse('2011-10-15'), Date.parse('2011-10-28')),
292
+ Timeframe.new(Date.parse('2011-11-08'), Date.parse('2011-11-12'))
293
+ ])
279
294
  end
280
295
  end
281
296
  end
data/timeframe.gemspec CHANGED
@@ -19,8 +19,10 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_development_dependency "rspec", "~> 1"
22
+ s.add_development_dependency "minitest"
23
23
  s.add_development_dependency 'home_run'
24
- s.add_dependency 'activesupport', '>=2.3.5'
25
- s.add_dependency 'i18n'
24
+ s.add_development_dependency 'rake'
25
+ s.add_runtime_dependency 'activesupport', '>=2.3.5'
26
+ s.add_runtime_dependency 'i18n'
27
+ s.add_runtime_dependency 'multi_json'
26
28
  end
metadata CHANGED
@@ -1,69 +1,120 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: timeframe
3
- version: !ruby/object:Gem::Version
4
- version: 0.0.11
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Andy Rossmeissl
9
14
  - Seamus Abshere
10
15
  - Derek Kastner
11
16
  autorequire:
12
17
  bindir: bin
13
18
  cert_chain: []
14
- date: 2011-07-05 00:00:00.000000000Z
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
17
- name: rspec
18
- requirement: &2162728480 !ruby/object:Gem::Requirement
19
+
20
+ date: 2012-01-06 00:00:00 Z
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: minitest
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
19
26
  none: false
20
- requirements:
21
- - - ~>
22
- - !ruby/object:Gem::Version
23
- version: '1'
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
24
34
  type: :development
25
- prerelease: false
26
- version_requirements: *2162728480
27
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
28
37
  name: home_run
29
- requirement: &2162728060 !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
30
40
  none: false
31
- requirements:
32
- - - ! '>='
33
- - !ruby/object:Gem::Version
34
- version: '0'
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
35
48
  type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rake
36
52
  prerelease: false
37
- version_requirements: *2162728060
38
- - !ruby/object:Gem::Dependency
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ type: :development
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
39
65
  name: activesupport
40
- requirement: &2162727520 !ruby/object:Gem::Requirement
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
41
68
  none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 9
73
+ segments:
74
+ - 2
75
+ - 3
76
+ - 5
45
77
  version: 2.3.5
46
78
  type: :runtime
47
- prerelease: false
48
- version_requirements: *2162727520
49
- - !ruby/object:Gem::Dependency
79
+ version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
50
81
  name: i18n
51
- requirement: &2162727100 !ruby/object:Gem::Requirement
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
52
84
  none: false
53
- requirements:
54
- - - ! '>='
55
- - !ruby/object:Gem::Version
56
- version: '0'
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
57
92
  type: :runtime
93
+ version_requirements: *id005
94
+ - !ruby/object:Gem::Dependency
95
+ name: multi_json
58
96
  prerelease: false
59
- version_requirements: *2162727100
97
+ requirement: &id006 !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ type: :runtime
107
+ version_requirements: *id006
60
108
  description: A Ruby class for describing and interacting with timeframes.
61
- email:
109
+ email:
62
110
  - andy@rossmeissl.net
63
111
  executables: []
112
+
64
113
  extensions: []
114
+
65
115
  extra_rdoc_files: []
66
- files:
116
+
117
+ files:
67
118
  - .document
68
119
  - .gitignore
69
120
  - Gemfile
@@ -71,36 +122,44 @@ files:
71
122
  - README.rdoc
72
123
  - Rakefile
73
124
  - lib/timeframe.rb
125
+ - lib/timeframe/core_ext/array.rb
74
126
  - lib/timeframe/version.rb
75
- - spec/spec.opts
76
127
  - spec/spec_helper.rb
77
128
  - spec/timeframe_spec.rb
78
129
  - timeframe.gemspec
79
130
  homepage: http://github.com/rossmeissl/timeframe
80
131
  licenses: []
132
+
81
133
  post_install_message:
82
134
  rdoc_options: []
83
- require_paths:
135
+
136
+ require_paths:
84
137
  - lib
85
- required_ruby_version: !ruby/object:Gem::Requirement
138
+ required_ruby_version: !ruby/object:Gem::Requirement
86
139
  none: false
87
- requirements:
88
- - - ! '>='
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ hash: 3
144
+ segments:
145
+ - 0
146
+ version: "0"
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
148
  none: false
93
- requirements:
94
- - - ! '>='
95
- - !ruby/object:Gem::Version
96
- version: '0'
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ hash: 3
153
+ segments:
154
+ - 0
155
+ version: "0"
97
156
  requirements: []
157
+
98
158
  rubyforge_project: timeframe
99
- rubygems_version: 1.8.5
159
+ rubygems_version: 1.8.8
100
160
  signing_key:
101
161
  specification_version: 3
102
162
  summary: Date intervals
103
- test_files:
104
- - spec/spec.opts
105
- - spec/spec_helper.rb
106
- - spec/timeframe_spec.rb
163
+ test_files: []
164
+
165
+ has_rdoc:
data/spec/spec.opts DELETED
@@ -1 +0,0 @@
1
- --color