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 +11 -3
- data/lib/date_time_precision/format/iso8601.rb +50 -0
- data/lib/date_time_precision/lib.rb +15 -1
- data/lib/date_time_precision/patch/1.8.7/time.rb +32 -0
- data/lib/date_time_precision/version.rb +1 -1
- data/spec/date_time_precision/date_time_precision_spec.rb +44 -0
- metadata +107 -112
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
|
-
- [
|
122
|
-
- [
|
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)
|
@@ -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
|
-
|
5
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
24
|
-
requirements:
|
23
|
+
requirements:
|
25
24
|
- - ">="
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 3
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
30
|
prerelease: false
|
31
31
|
type: :development
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
42
|
-
requirements:
|
37
|
+
requirements:
|
43
38
|
- - ">="
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
|
47
|
-
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
hash: 3
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
48
44
|
prerelease: false
|
49
45
|
type: :development
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
60
|
-
requirements:
|
51
|
+
requirements:
|
61
52
|
- - ">="
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
|
64
|
-
|
65
|
-
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
66
58
|
prerelease: false
|
67
59
|
type: :development
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
78
|
-
requirements:
|
65
|
+
requirements:
|
79
66
|
- - ">="
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
|
82
|
-
|
83
|
-
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
84
72
|
prerelease: false
|
85
73
|
type: :development
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
125
|
-
|
126
|
-
-
|
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
|
-
|
154
|
+
|
155
|
+
post_install_message:
|
161
156
|
rdoc_options: []
|
162
|
-
|
157
|
+
|
158
|
+
require_paths:
|
163
159
|
- lib
|
164
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
165
|
-
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
166
163
|
- - ">="
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
hash: 3
|
166
|
+
segments:
|
169
167
|
- 0
|
170
|
-
|
171
|
-
|
172
|
-
MA==
|
168
|
+
version: "0"
|
169
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
173
170
|
none: false
|
174
|
-
|
175
|
-
requirements:
|
171
|
+
requirements:
|
176
172
|
- - ">="
|
177
|
-
- !ruby/object:Gem::Version
|
178
|
-
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
hash: 3
|
175
|
+
segments:
|
179
176
|
- 0
|
180
|
-
|
181
|
-
version: !binary |-
|
182
|
-
MA==
|
183
|
-
none: false
|
177
|
+
version: "0"
|
184
178
|
requirements: []
|
185
|
-
|
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
|