date_time_precision 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -76,6 +76,13 @@ JSON.parse(json).to_date.precision
76
76
  => 2
77
77
  ```
78
78
 
79
+ ```ruby
80
+ require 'date_time_precision/format/iso8601'
81
+
82
+ Date.new(2000, 5).iso8601
83
+ => "2000-05"
84
+ ```
85
+
79
86
  ## Ruby Compatibility
80
87
 
81
88
  Tested in MRI 1.8.7/1.9.2/1.9.3/2.0.0, REE, JRuby 1.8/1.9, and Rubinius 1.8/1.9.
@@ -118,10 +125,11 @@ Or install it yourself as:
118
125
  ## Wishlist
119
126
 
120
127
  - [x] Support Time::mktime
121
- - [ ] Support Time::utc
122
- - [ ] Support Time::local
128
+ - [x] Support Time::utc and Time#utc
129
+ - [x] Support Time::local
130
+ - [.] Support correct generation (done) and parsing (not done) of the ISO 8601 format, which supports partial dates
131
+ - [ ] Support the various time zone methods (partially done)
123
132
  - [ ] Support easy string formatting based on precision
124
- - [ ] Support correct parsing and generation of ISO 8601 format, which supports partial dates
125
133
 
126
134
  ## Contributing
127
135
 
@@ -0,0 +1,50 @@
1
+ [Date, Time, DateTime].each do |klass|
2
+ klass.class_eval do
3
+ ISO8601_DATE_FRAGMENTS = %w(%0*d %02d %02d)
4
+ ISO8601_TIME_FRAGMENTS = %w(%02d %02d %02d)
5
+
6
+ if method_defined?(:xmlschema)
7
+ alias_method :xmlschema_without_precision, :xmlschema
8
+ end
9
+
10
+ def xmlschema
11
+ iso8601
12
+ end
13
+
14
+ if method_defined?(:iso8601)
15
+ alias_method :iso8601_without_precision, :iso8601
16
+ end
17
+ def iso8601
18
+ precision = self.precision || 0
19
+ format = ""
20
+ if precision > DateTimePrecision::NONE
21
+ # Add date part to format
22
+ format << ISO8601_DATE_FRAGMENTS.take([3,self.precision].min).join('-')
23
+ end
24
+
25
+ if precision > DateTimePrecision::DAY
26
+ format << "T#{ISO8601_TIME_FRAGMENTS.take(precision - 3).join(':')}"
27
+ end
28
+
29
+ output = sprintf(format, year < 0 ? 5 : 4, *self.fragments)
30
+
31
+ # Fractional seconds
32
+ if sec_frac? && sec_frac > 0
33
+ output << '.' + sprintf('%0*d', sec_frac, (subsec * 10**sec_frac).floor)
34
+ end
35
+
36
+ # Timezone
37
+ if precision > DateTimePrecision::DAY
38
+ if utc?
39
+ output << 'Z'
40
+ else
41
+ off = utc_offset
42
+ sign = off < 0 ? '-' : '+'
43
+ output << sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60))
44
+ end
45
+ end
46
+
47
+ output
48
+ end
49
+ end
50
+ end
@@ -1,11 +1,25 @@
1
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|
2
+ ['active_support/core_ext/date', 'active_support/core_ext/datetime', 'active_support/core_ext/time', 'active_support/time', 'active_support/time_with_zone'].each do |f|
3
3
  begin
4
4
  require f
5
5
  rescue LoadError; end
6
6
  end
7
7
  end
8
8
 
9
+ class Date
10
+ unless method_defined?(:utc?)
11
+ def utc?
12
+ offset == 0
13
+ end
14
+ end
15
+
16
+ unless method_defined?(:utc_offset)
17
+ def utc_offset
18
+ offset.numerator*3600
19
+ end
20
+ end
21
+ end
22
+
9
23
  module DateTimePrecision
10
24
  unless constants.include? "NONE"
11
25
  FRAC = 7
@@ -31,6 +31,38 @@ class Time
31
31
  t
32
32
  end
33
33
  private :make_time
34
+
35
+ alias_method :utc_without_prec, :utc
36
+ def utc(*args)
37
+ orig_args = args.shift(Time::MAX_PRECISION)
38
+ precision = self.precision(orig_args)
39
+ time_args = normalize_new_args(orig_args)
40
+
41
+ t = utc_without_prec(*[time_args, args].flatten)
42
+ t.precision = precision
43
+ t.attributes_set(orig_args)
44
+ t
45
+ end
46
+ alias_method :gm, :utc
47
+
48
+ alias_method :local_without_prec, :local
49
+ def local(*args)
50
+ orig_args = args.shift(Time::MAX_PRECISION)
51
+ precision = self.precision(orig_args)
52
+ time_args = normalize_new_args(orig_args)
53
+
54
+ t = local_without_prec(*[time_args, args].flatten)
55
+ t.precision = precision
56
+ t.attributes_set(orig_args)
57
+ t
58
+ end
59
+ end
60
+
61
+ alias_method :utc_without_prec, :utc
62
+ def utc(*args)
63
+ t = utc_without_prec(*args)
64
+ t.precision = self.precision
65
+ t
34
66
  end
35
67
 
36
68
  #def self.strptime(str='-4712-01-01', fmt='%F', sg=Date::ITALY)
@@ -1,3 +1,3 @@
1
1
  module DateTimePrecision
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -77,6 +77,22 @@ describe DateTimePrecision do
77
77
  Time.mktime(2000, 1, 1, nil, nil).precision.should == DateTimePrecision::DAY
78
78
  end
79
79
  end
80
+
81
+ context 'Time Zones' do
82
+ it 'should retain precision when switching to UTC' do
83
+ Time.mktime(2000).utc.precision.should == DateTimePrecision::YEAR
84
+ Time.mktime(2000).gmtime.precision.should == DateTimePrecision::YEAR
85
+ end
86
+
87
+ it 'should track precision when creating a time in UTC' do
88
+ Time.utc(1945, 10).precision.should == DateTimePrecision::MONTH
89
+ Time.gm(1945, 10).precision.should == DateTimePrecision::MONTH
90
+ end
91
+
92
+ it 'should track precision when creating a time in the local timezone' do
93
+ Time.local(2004, 5, 6).precision.should == DateTimePrecision::DAY
94
+ end
95
+ end
80
96
 
81
97
  context 'Parsing' do
82
98
  it 'should have second/frac precision when parsing a timestamp' do
@@ -167,6 +183,34 @@ describe DateTimePrecision do
167
183
  Time.mktime(*args)
168
184
  end
169
185
 
186
+ context 'ISO 8601' do
187
+ require 'date_time_precision/format/iso8601'
188
+
189
+ it 'should convert a date to ISO 8601' do
190
+ date.iso8601.should == "1989-03-11"
191
+ Date.new(1990, 5).iso8601.should == "1990-05"
192
+ Date.new(1800).iso8601.should == "1800"
193
+ end
194
+
195
+ it 'should convert a datetime to ISO 8601' do
196
+ datetime.iso8601.should == "1989-03-11T08:30:15Z"
197
+ DateTime.new(1900).iso8601.should == "1900"
198
+ DateTime.new(1990, 5).iso8601.should == "1990-05"
199
+ DateTime.new(1990, 5, 2).iso8601.should == "1990-05-02"
200
+ DateTime.new(1990, 5, 2, 12).iso8601.should == "1990-05-02T12Z"
201
+ DateTime.new(1990, 5, 2, 12, 30).iso8601.should == "1990-05-02T12:30Z"
202
+ end
203
+
204
+ it 'should convert a time to ISO 8601' do
205
+ Time.utc(1900).utc.iso8601.should == "1900"
206
+ Time.mktime(1990, 5).utc.iso8601.should == "1990-05"
207
+ Time.mktime(1990, 5, 2).utc.iso8601.should == "1990-05-02"
208
+ Time.utc(1990, 5, 2, 12).iso8601.should == "1990-05-02T12Z"
209
+ Time.utc(1990, 5, 2, 12, 30).utc.iso8601.should == "1990-05-02T12:30Z"
210
+ Time.utc(1990, 5, 2, 12, 30, 45).utc.iso8601.should == "1990-05-02T12:30:45Z"
211
+ end
212
+ end
213
+
170
214
  context 'Hash' do
171
215
  require 'date_time_precision/format/hash'
172
216
 
metadata CHANGED
@@ -1,129 +1,122 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: date_time_precision
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.4.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 11
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 0
10
+ version: 0.5.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - David Butler
9
- autorequire:
14
+ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2013-03-12 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rake
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: !binary |-
21
- MA==
17
+
18
+ date: 2013-03-30 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
22
22
  none: false
23
- requirement: !ruby/object:Gem::Requirement
24
- requirements:
23
+ requirements:
25
24
  - - ">="
26
- - !ruby/object:Gem::Version
27
- version: !binary |-
28
- MA==
29
- none: false
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
30
  prerelease: false
31
31
  type: :development
32
- - !ruby/object:Gem::Dependency
33
- name: rspec
34
- version_requirements: !ruby/object:Gem::Requirement
35
- requirements:
36
- - - ">="
37
- - !ruby/object:Gem::Version
38
- version: !binary |-
39
- MA==
32
+ name: rake
33
+ requirement: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
36
  none: false
41
- requirement: !ruby/object:Gem::Requirement
42
- requirements:
37
+ requirements:
43
38
  - - ">="
44
- - !ruby/object:Gem::Version
45
- version: !binary |-
46
- MA==
47
- none: false
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
48
44
  prerelease: false
49
45
  type: :development
50
- - !ruby/object:Gem::Dependency
51
- name: activesupport
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: !binary |-
57
- MA==
46
+ name: rspec
47
+ requirement: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ version_requirements: &id003 !ruby/object:Gem::Requirement
58
50
  none: false
59
- requirement: !ruby/object:Gem::Requirement
60
- requirements:
51
+ requirements:
61
52
  - - ">="
62
- - !ruby/object:Gem::Version
63
- version: !binary |-
64
- MA==
65
- none: false
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
66
58
  prerelease: false
67
59
  type: :development
68
- - !ruby/object:Gem::Dependency
69
- name: json
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: !binary |-
75
- MA==
60
+ name: activesupport
61
+ requirement: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ version_requirements: &id004 !ruby/object:Gem::Requirement
76
64
  none: false
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
65
+ requirements:
79
66
  - - ">="
80
- - !ruby/object:Gem::Version
81
- version: !binary |-
82
- MA==
83
- none: false
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
84
72
  prerelease: false
85
73
  type: :development
86
- - !ruby/object:Gem::Dependency
87
- name: virtus
88
- version_requirements: !ruby/object:Gem::Requirement
89
- requirements:
90
- - - '='
91
- - !ruby/object:Gem::Version
92
- version: 0.5.4
74
+ name: json
75
+ requirement: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ version_requirements: &id005 !ruby/object:Gem::Requirement
93
78
  none: false
94
- requirement: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - '='
97
- - !ruby/object:Gem::Version
79
+ requirements:
80
+ - - "="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ - 5
86
+ - 4
98
87
  version: 0.5.4
99
- none: false
100
88
  prerelease: false
101
89
  type: :development
102
- - !ruby/object:Gem::Dependency
103
- name: coercible
104
- version_requirements: !ruby/object:Gem::Requirement
105
- requirements:
106
- - - '='
107
- - !ruby/object:Gem::Version
108
- version: 0.0.1
90
+ name: virtus
91
+ requirement: *id005
92
+ - !ruby/object:Gem::Dependency
93
+ version_requirements: &id006 !ruby/object:Gem::Requirement
109
94
  none: false
110
- requirement: !ruby/object:Gem::Requirement
111
- requirements:
112
- - - '='
113
- - !ruby/object:Gem::Version
95
+ requirements:
96
+ - - "="
97
+ - !ruby/object:Gem::Version
98
+ hash: 29
99
+ segments:
100
+ - 0
101
+ - 0
102
+ - 1
114
103
  version: 0.0.1
115
- none: false
116
104
  prerelease: false
117
105
  type: :development
106
+ name: coercible
107
+ requirement: *id006
118
108
  description: Patches Date, Time, and DateTime ruby classes to keep track of precision
119
- email:
109
+ email:
120
110
  - dwbutler@ucla.edu
121
111
  executables: []
112
+
122
113
  extensions: []
114
+
123
115
  extra_rdoc_files: []
124
- files:
125
- - ".gitignore"
126
- - ".travis.yml"
116
+
117
+ files:
118
+ - .gitignore
119
+ - .travis.yml
127
120
  - Gemfile
128
121
  - LICENSE
129
122
  - README
@@ -137,6 +130,7 @@ files:
137
130
  - lib/date_time_precision/compat/coercible.rb
138
131
  - lib/date_time_precision/compat/virtus.rb
139
132
  - lib/date_time_precision/format/hash.rb
133
+ - lib/date_time_precision/format/iso8601.rb
140
134
  - lib/date_time_precision/format/json.rb
141
135
  - lib/date_time_precision/format/nil.rb
142
136
  - lib/date_time_precision/lib.rb
@@ -157,37 +151,38 @@ files:
157
151
  - spec/spec_helper.rb
158
152
  homepage: http://github.com/Spokeo/date_time_precision
159
153
  licenses: []
160
- post_install_message:
154
+
155
+ post_install_message:
161
156
  rdoc_options: []
162
- require_paths:
157
+
158
+ require_paths:
163
159
  - lib
164
- required_ruby_version: !ruby/object:Gem::Requirement
165
- requirements:
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
166
163
  - - ">="
167
- - !ruby/object:Gem::Version
168
- segments:
164
+ - !ruby/object:Gem::Version
165
+ hash: 3
166
+ segments:
169
167
  - 0
170
- hash: 2
171
- version: !binary |-
172
- MA==
168
+ version: "0"
169
+ required_rubygems_version: !ruby/object:Gem::Requirement
173
170
  none: false
174
- required_rubygems_version: !ruby/object:Gem::Requirement
175
- requirements:
171
+ requirements:
176
172
  - - ">="
177
- - !ruby/object:Gem::Version
178
- segments:
173
+ - !ruby/object:Gem::Version
174
+ hash: 3
175
+ segments:
179
176
  - 0
180
- hash: 2
181
- version: !binary |-
182
- MA==
183
- none: false
177
+ version: "0"
184
178
  requirements: []
185
- rubyforge_project:
179
+
180
+ rubyforge_project:
186
181
  rubygems_version: 1.8.24
187
- signing_key:
182
+ signing_key:
188
183
  specification_version: 3
189
184
  summary: Patches Date, Time, and DateTime ruby classes to keep track of precision
190
- test_files:
185
+ test_files:
191
186
  - spec/date_time_precision/active_support_spec.rb
192
187
  - spec/date_time_precision/compatibility_spec.rb
193
188
  - spec/date_time_precision/date_time_precision_spec.rb