date_time_precision 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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