timeframe 0.0.11 → 0.1.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.
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