date_time_precision 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -68,7 +68,7 @@ JSON.parse(json).to_date.precision
68
68
  => 2
69
69
  ```
70
70
 
71
- ## Compatibility
71
+ ## Ruby Compatibility
72
72
 
73
73
  Tested in MRI 1.8.7/1.9.2/1.9.3, REE, JRuby 1.8/1.9, and Rubinius 1.8/1.9.
74
74
 
@@ -76,6 +76,23 @@ Note that starting in MRI 1.9.3, the core Date/Time classes were rewritten in C,
76
76
  override internal functionality. Some functions are now implemented internally and are not exposed.
77
77
  The workaround is inefficient: `#parse` and `#strptime` perform the same work twice, once to get the precision and once inside the original C method.
78
78
 
79
+ ## Gem Compatibility
80
+
81
+ Sometimes other gems will use the Date/Time class in ways that don't preserve precision. If you want to use the DateTimePrecision gem with these
82
+ gems, any compatibility issues will most likely need to be patched within DateTimePrecision itself. This is because DateTimePrecision makes some
83
+ modifications to how the core Date/Time classes work. (For example, by allowing nil values to be passed to constructors.)
84
+
85
+ So far, the following gems are on the compatibility watch list:
86
+
87
+ - [x] [ActiveSupport](https://github.com/rails/rails/tree/master/activesupport)
88
+ - [x] [Virtus](https://github.com/solnic/virtus)
89
+ - [x] [Coercible](https://github.com/solnic/coercible)
90
+ - [ ] [Chronic](https://github.com/mojombo/chronic)
91
+ - [ ] [Timeliness](https://github.com/adzap/timeliness)
92
+ - [ ] [Timecop](https://github.com/travisjeffery/timecop)
93
+
94
+ If you know of any others, feel free to submit a pull request!
95
+
79
96
  ## Installation
80
97
 
81
98
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -3,4 +3,4 @@ require "bundler/gem_tasks"
3
3
 
4
4
  Dir['gem_tasks/**/*.rake'].each { |rake| load rake }
5
5
 
6
- task :default => [:spec, :active_support_spec]
6
+ task :default => [:spec, :active_support_spec, :compatibility_spec]
@@ -17,6 +17,10 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_development_dependency 'rake'
19
19
  gem.add_development_dependency 'rspec'
20
+
20
21
  gem.add_development_dependency 'activesupport'
21
22
  gem.add_development_dependency 'json'
23
+
24
+ gem.add_development_dependency 'virtus', '0.5.4'
25
+ gem.add_development_dependency 'coercible'
22
26
  end
@@ -10,4 +10,10 @@ desc "Run ActiveSupport spec"
10
10
  RSpec::Core::RakeTask.new(:active_support_spec) do |t|
11
11
  t.verbose = true
12
12
  t.pattern = "spec/date_time_precision/active_support_spec.rb"
13
+ end
14
+
15
+ desc "Run Compatibility spec"
16
+ RSpec::Core::RakeTask.new(:compatibility_spec) do |t|
17
+ t.verbose = true
18
+ t.pattern = "spec/date_time_precision/compatibility_spec.rb"
13
19
  end
@@ -2,6 +2,9 @@ source :rubygems
2
2
 
3
3
  gem 'rake'
4
4
  gem 'rspec'
5
- gem 'json'
6
5
 
7
- gem 'activesupport', '~> 2', :require => false
6
+ gem 'activesupport', '~> 2', :require => false
7
+
8
+ gem 'json'
9
+ gem 'virtus', '0.5.4'
10
+ gem 'coercible'
@@ -2,6 +2,9 @@ source :rubygems
2
2
 
3
3
  gem 'rake'
4
4
  gem 'rspec'
5
- gem 'json'
6
5
 
7
- gem 'activesupport', '~> 3', :require => false
6
+ gem 'activesupport', '~> 3', :require => false
7
+
8
+ gem 'json'
9
+ gem 'virtus', '0.5.4'
10
+ gem 'coercible'
@@ -0,0 +1,15 @@
1
+ if defined?(Coercible::Coercer::Hash)
2
+ class Coercible::Coercer::Hash
3
+ def to_date(value)
4
+ value.to_date
5
+ end
6
+
7
+ def to_datetime(value)
8
+ value.to_datetime
9
+ end
10
+
11
+ def to_time(value)
12
+ value.to_time
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ if defined?(Virtus::Coercion::Hash)
2
+ class Virtus::Coercion::Hash
3
+ class << self
4
+ def to_date(value)
5
+ value.to_date
6
+ end
7
+
8
+ def to_datetime(value)
9
+ value.to_datetime
10
+ end
11
+
12
+ def to_time(value)
13
+ value.to_time
14
+ end
15
+ end
16
+ end
17
+ end
@@ -22,7 +22,7 @@ class Hash
22
22
 
23
23
  protected
24
24
  def date_time_args
25
- [self[:year] || self[:y] || self['year'] || self['y'],
25
+ [self[:year] || self[:y] || self[:yr] || self['year'] || self['y'] || self['yr'],
26
26
  self[:mon] || self[:m] || self[:month] || self['mon'] || self['m'] || self['month'],
27
27
  self[:mday] || self[:d] || self[:day] || self['mday'] || self['d'] || self['day'],
28
28
  self[:hour] || self[:h] || self[:hr] || self['hour'] || self['h'] || self['hr'],
@@ -41,4 +41,7 @@ module DateTimePrecision
41
41
  [key, self.send(attribute_name)] if self.send("#{attribute_name}?")
42
42
  end.compact]
43
43
  end
44
- end
44
+ end
45
+
46
+ require 'date_time_precision/compat/virtus'
47
+ require 'date_time_precision/compat/coercible'
@@ -1,3 +1,11 @@
1
+ if defined?(ActiveSupport)
2
+ ['active_support/core_ext/date', 'active_support/core_ext/datetime', 'active_support/core_ext/time', 'active_support/time'].each do |f|
3
+ begin
4
+ require f
5
+ rescue LoadError; end
6
+ end
7
+ end
8
+
1
9
  module DateTimePrecision
2
10
  unless constants.include? "NONE"
3
11
  FRAC = 7
@@ -117,12 +125,12 @@ module DateTimePrecision
117
125
 
118
126
  def self.included(base)
119
127
  # Redefine any conversion methods so precision is preserved
120
- [:to_date, :to_time, :to_datetime].each do |m|
121
- orig = :"orig_#{m}"
122
- if base.method_defined?(m) && !base.method_defined?(orig)
128
+ [:to_date, :to_time, :to_datetime].each do |conversion_method|
129
+ orig = :"orig_#{conversion_method}"
130
+ if base.method_defined?(conversion_method) && !base.method_defined?(orig)
123
131
  base.class_exec {
124
- alias_method orig, m
125
- define_method(m) {
132
+ alias_method orig, conversion_method
133
+ define_method(conversion_method) {
126
134
  d = send(orig)
127
135
  d.precision = [self.precision, d.class::MAX_PRECISION].min
128
136
  d
@@ -1,3 +1,3 @@
1
1
  module DateTimePrecision
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -2,12 +2,6 @@ require 'spec_helper'
2
2
  require 'json'
3
3
  require 'active_support'
4
4
 
5
- require 'active_support/core_ext/date/conversions'
6
- require 'active_support/core_ext/time/conversions'
7
- begin
8
- require 'active_support/core_ext/datetime/conversions'
9
- rescue LoadError; end
10
-
11
5
  require 'date_time_precision'
12
6
 
13
7
  require 'date_time_precision/format/json'
@@ -15,10 +9,10 @@ require 'date_time_precision/format/json'
15
9
  describe DateTimePrecision, 'Conversions' do
16
10
  context 'when converting from Date to Time or DateTime' do
17
11
  it 'should maintain precision' do
18
- d = Date.new(2005, 1, 2)
19
- d.precision.should == DateTimePrecision::DAY
20
- d.to_date.precision.should == DateTimePrecision::DAY
21
- d.to_datetime.precision.should == DateTimePrecision::DAY
12
+ d = Date.new(2005, 1)
13
+ d.precision.should == DateTimePrecision::MONTH
14
+ d.to_date.precision.should == DateTimePrecision::MONTH
15
+ d.to_datetime.precision.should == DateTimePrecision::MONTH
22
16
  end
23
17
  end
24
18
 
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+ require 'virtus'
3
+ require 'coercible'
4
+ require 'date_time_precision'
5
+ require 'date_time_precision/format/hash'
6
+
7
+ class VirtusModel
8
+ include Virtus
9
+
10
+ attribute :date, Date
11
+ attribute :datetime, DateTime
12
+ attribute :time, Time
13
+ end
14
+
15
+ describe DateTimePrecision do
16
+ context 'compatibility' do
17
+
18
+ let(:date_hash) { {:y => 1990} }
19
+ let(:datetime_hash) { {'year' => 1800, 'mon' => 2} }
20
+ let(:time_hash) { {:yr => 1950, 'm' => 5, :day => 19, :hr => 5} }
21
+
22
+ context 'with Virtus' do
23
+ let(:model) { VirtusModel.new }
24
+ before(:all) do
25
+ model.date = date_hash
26
+ model.datetime = datetime_hash
27
+ model.time = time_hash
28
+ end
29
+
30
+ context 'when coercing a hash to a Date' do
31
+ subject { model.date }
32
+
33
+ it { should be_a Date }
34
+ its(:year) { should == 1990 }
35
+ its(:precision) { should == DateTimePrecision::YEAR }
36
+ end
37
+
38
+ context 'when coercing a hash to a DateTime' do
39
+ subject { model.datetime }
40
+
41
+ it { should be_a DateTime }
42
+ its(:year) { should == 1800 }
43
+ its(:month) { should == 2 }
44
+ its(:precision) { should == DateTimePrecision::MONTH }
45
+ end
46
+
47
+ context 'when coercing a hash to a Time' do
48
+ subject { model.time }
49
+
50
+ it { should be_a Time }
51
+ its(:year) { should == 1950 }
52
+ its(:month) { should == 5 }
53
+ its(:day) { should == 19 }
54
+ its(:hour) { should == 5 }
55
+ its(:precision) { should == DateTimePrecision::HOUR }
56
+ end
57
+ end
58
+
59
+ context 'with Coercible' do
60
+ let(:coercer) { Coercible::Coercer::Hash.new }
61
+
62
+ context 'when coercing a hash to a Date' do
63
+ subject { coercer.to_date(date_hash) }
64
+
65
+ it { should be_a Date }
66
+ its(:year) { should == 1990 }
67
+ its(:precision) { should == DateTimePrecision::YEAR }
68
+ end
69
+
70
+ context 'when coercing a hash to a DateTime' do
71
+ subject { coercer.to_datetime(datetime_hash) }
72
+
73
+ it { should be_a DateTime }
74
+ its(:year) { should == 1800 }
75
+ its(:month) { should == 2 }
76
+ its(:precision) { should == DateTimePrecision::MONTH }
77
+ end
78
+
79
+ context 'when coercing a hash to a Time' do
80
+ subject { coercer.to_time(time_hash) }
81
+
82
+ it { should be_a Time }
83
+ its(:year) { should == 1950 }
84
+ its(:month) { should == 5 }
85
+ its(:day) { should == 19 }
86
+ its(:hour) { should == 5 }
87
+ its(:precision) { should == DateTimePrecision::HOUR }
88
+ end
89
+ end
90
+ end
91
+ end
metadata CHANGED
@@ -1,87 +1,118 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: date_time_precision
3
- version: !ruby/object:Gem::Version
4
- version: 0.2.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - David Butler
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2013-02-05 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rake
16
- requirement: !ruby/object:Gem::Requirement
17
+
18
+ date: 2013-02-06 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
17
22
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
23
30
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
31
+ type: :development
32
+ name: rake
33
+ requirement: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ version_requirements: &id002 !ruby/object:Gem::Requirement
25
36
  none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
30
- - !ruby/object:Gem::Dependency
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ prerelease: false
45
+ type: :development
31
46
  name: rspec
32
- requirement: !ruby/object:Gem::Requirement
47
+ requirement: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ version_requirements: &id003 !ruby/object:Gem::Requirement
33
50
  none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: '0'
38
- type: :development
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
39
58
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
46
- - !ruby/object:Gem::Dependency
59
+ type: :development
47
60
  name: activesupport
48
- requirement: !ruby/object:Gem::Requirement
61
+ requirement: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ version_requirements: &id004 !ruby/object:Gem::Requirement
49
64
  none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
55
72
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
73
+ type: :development
63
74
  name: json
64
- requirement: !ruby/object:Gem::Requirement
75
+ requirement: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ version_requirements: &id005 !ruby/object:Gem::Requirement
65
78
  none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
- type: :development
79
+ requirements:
80
+ - - "="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ - 5
86
+ - 4
87
+ version: 0.5.4
71
88
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
89
+ type: :development
90
+ name: virtus
91
+ requirement: *id005
92
+ - !ruby/object:Gem::Dependency
93
+ version_requirements: &id006 !ruby/object:Gem::Requirement
73
94
  none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ prerelease: false
103
+ type: :development
104
+ name: coercible
105
+ requirement: *id006
78
106
  description: Patches Date, Time, and DateTime ruby classes to keep track of precision
79
- email:
107
+ email:
80
108
  - dwbutler@ucla.edu
81
109
  executables: []
110
+
82
111
  extensions: []
112
+
83
113
  extra_rdoc_files: []
84
- files:
114
+
115
+ files:
85
116
  - .gitignore
86
117
  - .travis.yml
87
118
  - Gemfile
@@ -94,6 +125,8 @@ files:
94
125
  - gemfiles/activesupport2.gemfile
95
126
  - gemfiles/activesupport3.gemfile
96
127
  - lib/date_time_precision.rb
128
+ - lib/date_time_precision/compat/coercible.rb
129
+ - lib/date_time_precision/compat/virtus.rb
97
130
  - lib/date_time_precision/format/hash.rb
98
131
  - lib/date_time_precision/format/json.rb
99
132
  - lib/date_time_precision/format/nil.rb
@@ -110,39 +143,44 @@ files:
110
143
  - lib/date_time_precision/patch/1.9.3/time.rb
111
144
  - lib/date_time_precision/version.rb
112
145
  - spec/date_time_precision/active_support_spec.rb
146
+ - spec/date_time_precision/compatibility_spec.rb
113
147
  - spec/date_time_precision/date_time_precision_spec.rb
114
148
  - spec/spec_helper.rb
115
149
  homepage: http://github.com/Spokeo/date_time_precision
116
150
  licenses: []
151
+
117
152
  post_install_message:
118
153
  rdoc_options: []
119
- require_paths:
154
+
155
+ require_paths:
120
156
  - lib
121
- required_ruby_version: !ruby/object:Gem::Requirement
157
+ required_ruby_version: !ruby/object:Gem::Requirement
122
158
  none: false
123
- requirements:
124
- - - ! '>='
125
- - !ruby/object:Gem::Version
126
- version: '0'
127
- segments:
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ hash: 3
163
+ segments:
128
164
  - 0
129
- hash: 3562610931592917135
130
- required_rubygems_version: !ruby/object:Gem::Requirement
165
+ version: "0"
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
167
  none: false
132
- requirements:
133
- - - ! '>='
134
- - !ruby/object:Gem::Version
135
- version: '0'
136
- segments:
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ hash: 3
172
+ segments:
137
173
  - 0
138
- hash: 3562610931592917135
174
+ version: "0"
139
175
  requirements: []
176
+
140
177
  rubyforge_project:
141
178
  rubygems_version: 1.8.24
142
179
  signing_key:
143
180
  specification_version: 3
144
181
  summary: Patches Date, Time, and DateTime ruby classes to keep track of precision
145
- test_files:
182
+ test_files:
146
183
  - spec/date_time_precision/active_support_spec.rb
184
+ - spec/date_time_precision/compatibility_spec.rb
147
185
  - spec/date_time_precision/date_time_precision_spec.rb
148
186
  - spec/spec_helper.rb