timeframe 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ 0.2.0 / 2012-04-24
2
+
3
+ * Breaking changes
4
+
5
+ * Use ISO8601 for JSON output. No sense in coming up with our own structure. Timeframe.parse will still understand the old startDate/endDate hash structure.
6
+
7
+ * Enhancements
8
+
9
+ * New MultiJson syntax
10
+ * Simplify and DRY.
11
+ * Tested on MRI 1.8, MRI 1.9, and JRuby 1.6.7+
data/Gemfile CHANGED
@@ -4,5 +4,6 @@ gemspec
4
4
 
5
5
  # development dependencies
6
6
  gem 'yard'
7
- gem 'minitest'
8
7
  gem 'rake'
8
+ gem 'minitest'
9
+ gem 'minitest-reporters'
@@ -2,6 +2,17 @@
2
2
 
3
3
  A Ruby class for describing and interacting with timeframes.
4
4
 
5
+ ## Real-world usage
6
+
7
+ <p><a href="http://brighterplanet.com"><img src="https://s3.amazonaws.com/static.brighterplanet.com/assets/logos/flush-left/inline/green/rasterized/brighter_planet-160-transparent.png" alt="Brighter Planet logo"/></a></p>
8
+
9
+ We use `timeframe` for [data science at Brighter Planet](http://brighterplanet.com/research) and in production at
10
+
11
+ * [Brighter Planet's impact estimate web service](http://impact.brighterplanet.com)
12
+ * [Brighter Planet's reference data web service](http://data.brighterplanet.com)
13
+
14
+ Originally proposed to us by [the awesome programmers at fingertips](http:/fngtps.com)
15
+
5
16
  ## Based on ISO 8601
6
17
 
7
18
  As [documented by wikipedia](http://en.wikipedia.org/wiki/ISO_8601#Time_intervals), time intervals are like:
@@ -33,8 +44,6 @@ http://rdoc.info/projects/rossmeissl/timeframe
33
44
 
34
45
  ## Acknowledgements
35
46
 
36
- The good parts of Timeframe all came from the gentlemen at Fingertips[http://fngtps.com].
37
-
38
47
  Thanks to @artemk for https://github.com/rossmeissl/timeframe/pull/5
39
48
 
40
49
  ## Copyright
data/Rakefile CHANGED
@@ -1,15 +1,14 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
3
 
4
+ require 'rake'
4
5
  require 'rake/testtask'
5
-
6
- Rake::TestTask.new do |t|
7
- t.libs.push 'lib'
8
- t.test_files = FileList['spec/**/*spec.rb']
9
- t.verbose = true
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.pattern = 'test/**/test_*.rb'
9
+ test.verbose = true
10
10
  end
11
11
 
12
-
13
12
  task :default => :test
14
13
 
15
14
  require 'yard'
@@ -76,7 +76,7 @@ class Timeframe
76
76
  when ::String
77
77
  str = input.strip
78
78
  if str.start_with?('{')
79
- from_hash MultiJson.decode(str)
79
+ from_hash MultiJson.load(str)
80
80
  elsif input =~ /\A\d\d\d\d\z/
81
81
  from_year input
82
82
  else
@@ -279,11 +279,11 @@ class Timeframe
279
279
  end
280
280
 
281
281
  def to_json(*)
282
- %({"startDate":"#{start_date.iso8601}","endDate":"#{end_date.iso8601}"})
282
+ iso8601
283
283
  end
284
284
 
285
285
  def as_json(*)
286
- { :startDate => start_date.iso8601, :endDate => end_date.iso8601 }
286
+ iso8601
287
287
  end
288
288
 
289
289
  # An ISO 8601 "time interval" like YYYY-MM-DD/YYYY-MM-DD
@@ -3,17 +3,17 @@ class Timeframe
3
3
  # Internal use.
4
4
  #
5
5
  # Parses a duration like 'P1Y2M4DT3H4M2S'
6
- class Duration < ::Struct.new(:date_part, :time_part)
7
- def seconds
8
- (y*31_556_926 + m*2_629_743.83 + d*86_400 + h*3_600 + minutes*60 + s).ceil
6
+ class Duration
7
+ attr_reader :seconds
8
+ def initialize(date_part, time_part)
9
+ y = parse date_part, :Y
10
+ m = parse date_part, :M
11
+ d = parse date_part, :D
12
+ h = parse time_part, :H
13
+ minutes = parse time_part, :M
14
+ s = parse time_part, :S
15
+ @seconds = (y*31_556_926 + m*2_629_743.83 + d*86_400 + h*3_600 + minutes*60 + s).ceil
9
16
  end
10
- private
11
- def y; @y ||= parse(date_part, :Y); end
12
- def m; @m ||= parse(date_part, :M); end
13
- def d; @d ||= parse(date_part, :D); end
14
- def h; @h ||= parse(time_part, :H); end
15
- def minutes; @minutes ||= parse(time_part, :M); end
16
- def s; @s ||= parse(time_part, :S); end
17
17
  def parse(part, indicator)
18
18
  if part =~ /(\d+)#{indicator.to_s}/
19
19
  $1.to_f
@@ -27,10 +27,11 @@ class Timeframe
27
27
  class Side
28
28
  # We add one day because so that it can be excluded per timeframe's conventions.
29
29
  EXCLUDED_LAST_DAY = 86_400
30
- attr_reader :date_part, :time_part
30
+ attr_reader :date_part
31
+ attr_reader :time_part
31
32
  def to_time(counterpart)
32
33
  if date_part.start_with?('P')
33
- counterpart.resolve_time(self) + resolve_offset + EXCLUDED_LAST_DAY
34
+ counterpart.resolve_time(self) + offset + EXCLUDED_LAST_DAY
34
35
  else
35
36
  resolve_time counterpart
36
37
  end
@@ -50,7 +51,7 @@ class Timeframe
50
51
  Time.parse [date_part, time_part].join('T')
51
52
  end
52
53
  # When A is a period, it counts as a negative offset to B.
53
- def resolve_offset
54
+ def offset
54
55
  0.0 - Duration.new(date_part, time_part).seconds
55
56
  end
56
57
  end
@@ -85,7 +86,7 @@ class Timeframe
85
86
  end
86
87
  Time.parse [filled_in_date_part, filled_in_time_part].join('T')
87
88
  end
88
- def resolve_offset
89
+ def offset
89
90
  Duration.new(date_part, time_part).seconds
90
91
  end
91
92
  end
@@ -1,3 +1,3 @@
1
1
  class Timeframe
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'minitest/spec'
5
+ require 'minitest/autorun'
6
+ require 'minitest/reporters'
7
+ MiniTest::Unit.runner = MiniTest::SuiteRunner.new
8
+ MiniTest::Unit.runner.reporters << MiniTest::Reporters::SpecReporter.new
9
+
10
+ require 'timeframe'
11
+ require 'timeframe/core_ext/array'
@@ -1,4 +1,4 @@
1
- require File.expand_path('../spec_helper', __FILE__)
1
+ require 'helper'
2
2
 
3
3
  describe Timeframe do
4
4
  describe 'initialization' do
@@ -275,11 +275,11 @@ describe Timeframe do
275
275
  end
276
276
  it 'understands JSON' do
277
277
  json =<<-EOS
278
- {"startDate":"2009-05-01", "endDate":"2009-06-01"}
278
+ 2009-05-01/2009-06-01
279
279
  EOS
280
280
  Timeframe.parse(json).must_equal Timeframe.new(:year => 2009, :month => 5)
281
281
  end
282
- it 'understands a Ruby hash' do
282
+ it 'understands a particular style of Ruby hash we used to emit (deprecated)' do
283
283
  hsh = { :startDate => '2009-05-01', :endDate => '2009-06-01' }
284
284
  Timeframe.parse(hsh).must_equal Timeframe.new(:year => 2009, :month => 5)
285
285
  Timeframe.parse(hsh.stringify_keys).must_equal Timeframe.new(:year => 2009, :month => 5)
@@ -288,7 +288,7 @@ EOS
288
288
 
289
289
  describe '#to_json' do
290
290
  it 'should generate JSON (test fails on ruby 1.8)' do
291
- Timeframe.new(:year => 2009).to_json.must_equal %({"startDate":"2009-01-01","endDate":"2010-01-01"})
291
+ Timeframe.new(:year => 2009).to_json.must_equal %{2009-01-01/2010-01-01}
292
292
  end
293
293
  it 'understands its own #to_json' do
294
294
  t = Timeframe.new(:year => 2009, :month => 5)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timeframe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-03-07 00:00:00.000000000 Z
14
+ date: 2012-04-24 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
18
- requirement: &2164797740 !ruby/object:Gem::Requirement
18
+ requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,15 @@ dependencies:
23
23
  version: 2.3.5
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *2164797740
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: 2.3.5
27
32
  - !ruby/object:Gem::Dependency
28
33
  name: i18n
29
- requirement: &2164797080 !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
30
35
  none: false
31
36
  requirements:
32
37
  - - ! '>='
@@ -34,10 +39,15 @@ dependencies:
34
39
  version: '0'
35
40
  type: :runtime
36
41
  prerelease: false
37
- version_requirements: *2164797080
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
38
48
  - !ruby/object:Gem::Dependency
39
49
  name: multi_json
40
- requirement: &2164796260 !ruby/object:Gem::Requirement
50
+ requirement: !ruby/object:Gem::Requirement
41
51
  none: false
42
52
  requirements:
43
53
  - - ! '>='
@@ -45,7 +55,12 @@ dependencies:
45
55
  version: '0'
46
56
  type: :runtime
47
57
  prerelease: false
48
- version_requirements: *2164796260
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
49
64
  description: A Ruby class for describing and interacting with timeframes.
50
65
  email:
51
66
  - andy@rossmeissl.net
@@ -53,8 +68,8 @@ executables: []
53
68
  extensions: []
54
69
  extra_rdoc_files: []
55
70
  files:
56
- - .document
57
71
  - .gitignore
72
+ - CHANGELOG
58
73
  - Gemfile
59
74
  - LICENSE
60
75
  - README.markdown
@@ -63,8 +78,8 @@ files:
63
78
  - lib/timeframe/core_ext/array.rb
64
79
  - lib/timeframe/iso_8601.rb
65
80
  - lib/timeframe/version.rb
66
- - spec/spec_helper.rb
67
- - spec/timeframe_spec.rb
81
+ - test/helper.rb
82
+ - test/test_timeframe.rb
68
83
  - timeframe.gemspec
69
84
  homepage: http://github.com/rossmeissl/timeframe
70
85
  licenses: []
@@ -86,11 +101,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
101
  version: '0'
87
102
  requirements: []
88
103
  rubyforge_project: timeframe
89
- rubygems_version: 1.8.15
104
+ rubygems_version: 1.8.21
90
105
  signing_key:
91
106
  specification_version: 3
92
107
  summary: Date intervals
93
108
  test_files:
94
- - spec/spec_helper.rb
95
- - spec/timeframe_spec.rb
109
+ - test/helper.rb
110
+ - test/test_timeframe.rb
96
111
  has_rdoc:
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.markdown
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
@@ -1,9 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- Bundler.setup
4
- require 'minitest/spec'
5
- require 'minitest/autorun'
6
- $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
- require File.expand_path('../../lib/timeframe.rb', __FILE__)
9
- require File.expand_path('../../lib/timeframe/core_ext/array.rb', __FILE__)