date_time_precision 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -21,11 +21,15 @@ The behavior of these classes should otherwise remain unchanged.
21
21
  require 'date_time_precision'
22
22
 
23
23
  d = Date.new(2000)
24
- d.precision # => DateTimePrecision::YEAR
24
+ d.precision # => DateTimePrecision::YEAR
25
25
 
26
26
  t = Time::parse("2001-05")
27
- t.precision # => DateTimePrecision::MONTH
27
+ t.precision # => DateTimePrecision::MONTH
28
28
  t.precision > d.precision # => true
29
+
30
+ dt = DateTime.new(nil, 7, 4)
31
+ dt.year? # => false
32
+ dt.month? # => true
29
33
  ```
30
34
 
31
35
  The gem adds the following instance methods to Date, Time, and/or DateTime:
@@ -54,7 +58,11 @@ hash = date.to_h
54
58
  => {:year=>2000, :mon=>10}
55
59
 
56
60
  hash.to_date.precision
57
- => 2
61
+ => 2
62
+
63
+ birthday = Date.new(nil, 11, 12)
64
+ birthday.to_h
65
+ => {:mon => 11, :day => 12}
58
66
  ```
59
67
 
60
68
  ```ruby
@@ -113,6 +121,7 @@ Or install it yourself as:
113
121
  - [ ] Support Time::utc
114
122
  - [ ] Support Time::local
115
123
  - [ ] Support easy string formatting based on precision
124
+ - [ ] Support correct parsing and generation of ISO 8601 format, which supports partial dates
116
125
 
117
126
  ## Contributing
118
127
 
@@ -4,7 +4,7 @@ class Hash
4
4
  DATE_FORMATS = {
5
5
  :short => [:y, :m, :d],
6
6
  :long => [:year, :month, :day],
7
- :ruby => [:year, :mon, :mday, :hour, :min, :sec, :sec_frac]
7
+ :ruby => [:year, :mon, :day, :hour, :min, :sec, :sec_frac]
8
8
  }
9
9
  DATE_FORMATS[:default] = DATE_FORMATS[:ruby]
10
10
 
@@ -20,10 +20,20 @@ module DateTimePrecision
20
20
  # Default values for y,m,d,h,m,s,frac
21
21
  NEW_DEFAULTS = [-4712,1,1,0,0,0,0]
22
22
 
23
- DATE_ATTRIBUTES = {
23
+ DATE_ATTRIBUTES = [
24
+ :year,
25
+ :mon,
26
+ :day,
27
+ :hour,
28
+ :min,
29
+ :sec,
30
+ :sec_frac
31
+ ]
32
+
33
+ DATE_ATTRIBUTE_PRECISIONS = {
24
34
  :year => YEAR,
25
35
  :mon => MONTH,
26
- :mday => DAY,
36
+ :day => DAY,
27
37
  :hour => HOUR,
28
38
  :min => MIN,
29
39
  :sec => SEC,
@@ -56,28 +66,21 @@ module DateTimePrecision
56
66
  MIN
57
67
  when val[:hour]
58
68
  HOUR
59
- when val[:mday], val[:day]
69
+ when val[:mday], val[:day], val[:d]
60
70
  DAY
61
- when val[:mon], val[:month]
71
+ when val[:mon], val[:month], val[:m]
62
72
  MONTH
63
- when val[:year]
73
+ when val[:year], val[:y]
64
74
  YEAR
65
75
  else
66
76
  NONE
67
77
  end
68
78
  when Array
69
- val.compact.length
79
+ val.index{|v| v.nil?} || val.length
70
80
  else
71
81
  NONE
72
82
  end
73
83
  end
74
-
75
- # Define attribute query methods
76
- DATE_ATTRIBUTES.each do |attribute_name, precision|
77
- define_method "#{attribute_name}?" do
78
- return self.precision >= precision
79
- end
80
- end
81
84
 
82
85
  def fragments
83
86
  frags = []
@@ -116,8 +119,10 @@ module DateTimePrecision
116
119
 
117
120
  def normalize_new_args(args)
118
121
  unless args.all?
119
- args = args.compact
120
- args = args.concat(DateTimePrecision::NEW_DEFAULTS.slice(args.length, DateTimePrecision::NEW_DEFAULTS.length - args.length))
122
+ # Replace nil values with their corresponding default values
123
+ args = args.each_with_index.map do |val,i|
124
+ val || DateTimePrecision::NEW_DEFAULTS[i]
125
+ end
121
126
  end
122
127
  args.take(self::MAX_PRECISION)
123
128
  end
@@ -133,6 +138,9 @@ module DateTimePrecision
133
138
  define_method(conversion_method) {
134
139
  d = send(orig)
135
140
  d.precision = [self.precision, d.class::MAX_PRECISION].min
141
+ DATE_ATTRIBUTES.each do |attribute|
142
+ d.instance_variable_set(:"@#{attribute}_set", self.instance_variable_get(:"@#{attribute}_set"))
143
+ end
136
144
  d
137
145
  }
138
146
  }
@@ -142,7 +150,29 @@ module DateTimePrecision
142
150
  # Extend with this module's class methods
143
151
  base.extend(ClassMethods)
144
152
 
145
- base.instance_eval do
153
+ # Define attribute query methods
154
+ DATE_ATTRIBUTE_PRECISIONS.each do |attribute_name, precision|
155
+ #next unless precision <= base::MAX_PRECISION
156
+
157
+ base.class_eval <<-EOM, __FILE__, __LINE__
158
+ def #{attribute_name}?
159
+ return !@#{attribute_name}_set.nil? ? @#{attribute_name}_set : (self.precision >= #{precision})
160
+ end
161
+
162
+ def #{attribute_name}_set=(val)
163
+ @#{attribute_name}_set = !!val
164
+ end
165
+ protected :#{attribute_name}_set=
166
+ EOM
167
+ end
168
+
169
+ base.class_eval <<-EOM, __FILE__, __LINE__
170
+ def attributes_set(*vals)
171
+ #{DATE_ATTRIBUTES.map{|attribute| "@#{attribute}_set"}.join(', ')} = *(vals.flatten.map{|v| !!v})
172
+ end
173
+ EOM
174
+
175
+ base.class_eval do
146
176
  if method_defined?(:usec)
147
177
  alias_method :usec?, :sec_frac?
148
178
  alias_method :sec_frac, :usec
@@ -155,7 +185,7 @@ module DateTimePrecision
155
185
  alias_method :month?, :mon?
156
186
 
157
187
  alias_method :mday, :day
158
- alias_method :day?, :mday?
188
+ alias_method :mday?, :day?
159
189
  end
160
190
  end
161
191
  end
@@ -2,9 +2,9 @@ require 'date_time_precision/lib'
2
2
  require 'date'
3
3
 
4
4
  class Date
5
- include DateTimePrecision
6
-
7
5
  MAX_PRECISION = DateTimePrecision::DAY
6
+
7
+ include DateTimePrecision
8
8
 
9
9
  def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY)
10
10
  elem = _parse(str, comp)
@@ -23,21 +23,19 @@ class Date
23
23
  end
24
24
 
25
25
  def self.civil(y=nil, m=nil, d=nil, sg=ITALY)
26
- vals = [y,m,d]
27
- precision = DateTimePrecision::precision(vals)
28
- unless vals.all?
29
- vals = vals.compact
30
- vals = vals.concat(NEW_DEFAULTS.slice(vals.length, NEW_DEFAULTS.length - vals.length))
31
- end
32
- y,m,d = vals
26
+ args = [y,m,d]
27
+ precision = self.precision(args)
28
+
29
+ args = normalize_new_args(args)
33
30
 
34
- unless jd = valid_civil?(y, m, d, sg)
31
+ unless jd = valid_civil?(*args)
35
32
  raise ArgumentError, 'invalid date'
36
33
  end
37
34
 
38
- d = new!(jd_to_ajd(jd, 0, 0), 0, sg)
39
- d.precision = precision
40
- d
35
+ date = new!(jd_to_ajd(jd, 0, 0), 0, sg)
36
+ date.precision = precision
37
+ date.attributes_set(y,m,d)
38
+ date
41
39
  end
42
40
 
43
41
  class << self; alias_method :new, :civil end
@@ -2,9 +2,9 @@ require 'date_time_precision/lib'
2
2
  require 'date'
3
3
 
4
4
  class DateTime < Date
5
- include DateTimePrecision
6
-
7
5
  MAX_PRECISION = DateTimePrecision::SEC
6
+
7
+ include DateTimePrecision
8
8
 
9
9
  def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY)
10
10
  elem = _parse(str, comp)
@@ -15,15 +15,11 @@ class DateTime < Date
15
15
  end
16
16
 
17
17
  def self.civil(y=nil, m=nil, d=nil, h=nil, min=nil, s=nil, of=0, sg=ITALY)
18
- vals = [y,m,d,h,min,s]
19
- precision = DateTimePrecision::precision(vals)
20
- unless vals.all?
21
- vals = vals.compact
22
- vals = vals.concat(NEW_DEFAULTS.slice(vals.length, NEW_DEFAULTS.length - vals.length))
23
- end
24
- y,m,d,h,min,s = vals
18
+ time_args = [y,m,d,h,min,s]
19
+ precision = self.precision(time_args)
20
+ time_args = normalize_new_args(time_args)
25
21
 
26
- unless (jd = valid_civil?(y, m, d, sg)) && (fr = valid_time?(h, min, s))
22
+ unless (jd = valid_civil?(time_args[0], time_args[1], time_args[2], sg)) && (fr = valid_time?(time_args[3], time_args[4], time_args[5]))
27
23
  raise ArgumentError, 'invalid date'
28
24
  end
29
25
  if String === of
@@ -31,6 +27,7 @@ class DateTime < Date
31
27
  end
32
28
  dt = new!(jd_to_ajd(jd, fr, of), of, sg)
33
29
  dt.precision = precision
30
+ dt.attributes_set(y,m,d,h,min,s)
34
31
  dt
35
32
  end
36
33
 
@@ -2,30 +2,32 @@ require 'date_time_precision/lib'
2
2
  require 'time'
3
3
 
4
4
  class Time
5
- include DateTimePrecision
6
-
7
5
  MAX_PRECISION = DateTimePrecision::SEC
6
+
7
+ include DateTimePrecision
8
8
 
9
9
  class << self
10
10
  alias_method :mktime_orig, :mktime
11
11
  def mktime(*args)
12
- time_args = args.shift(Time::MAX_PRECISION)
13
- precision = self.precision(time_args)
14
- time_args = normalize_new_args(time_args)
12
+ orig_args = args.shift(Time::MAX_PRECISION)
13
+ precision = self.precision(orig_args)
14
+ time_args = normalize_new_args(orig_args)
15
15
 
16
16
  t = mktime_orig(*[time_args, args].flatten)
17
17
  t.precision = precision
18
+ t.attributes_set(orig_args)
18
19
  t
19
20
  end
20
21
 
21
22
  alias_method :make_time_orig, :make_time
22
23
  def make_time(*args)
23
- time_args = args.shift(Time::MAX_PRECISION)
24
- precision = self.precision(time_args)
25
- time_args = normalize_new_args(time_args)
24
+ orig_args = args.shift(Time::MAX_PRECISION)
25
+ precision = self.precision(orig_args)
26
+ time_args = normalize_new_args(orig_args)
26
27
 
27
28
  t = make_time_orig(*[time_args, args].flatten)
28
29
  t.precision = precision
30
+ t.attributes_set(orig_args)
29
31
  t
30
32
  end
31
33
  private :make_time
@@ -1,64 +1,21 @@
1
- require 'date_time_precision/lib'
2
- require 'date'
1
+ require 'date_time_precision/patch/1.8.7/date'
3
2
 
4
3
  class Date
5
- include DateTimePrecision
6
-
7
- MAX_PRECISION = DateTimePrecision::DAY
8
-
9
- def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY)
10
- elem = _parse(str, comp)
11
- precision = DateTimePrecision::precision(elem)
12
- d = new_by_frags(elem, sg)
13
- d.precision = precision
14
- d
15
- end
16
-
17
- def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
18
- elem = _strptime(str, fmt)
19
- precision = DateTimePrecision::precision(elem)
20
- d = new_by_frags(elem, sg)
21
- d.precision = precision
22
- d
23
- end
24
-
25
4
  def self.civil(y=nil, m=nil, d=nil, sg=ITALY)
26
- vals = [y,m,d]
27
- precision = DateTimePrecision::precision(vals)
28
- unless vals.all?
29
- vals = vals.compact
30
- vals = vals.concat(NEW_DEFAULTS.slice(vals.length, NEW_DEFAULTS.length - vals.length))
31
- end
32
- y,m,d = vals
5
+ args = [y,m,d]
6
+ precision = self.precision(args)
7
+
8
+ args = normalize_new_args(args)
33
9
 
34
- unless jd = _valid_civil?(y, m, d, sg)
10
+ unless jd = _valid_civil?(*[args, sg].flatten)
35
11
  raise ArgumentError, 'invalid date'
36
12
  end
37
13
 
38
- d = new!(jd_to_ajd(jd, 0, 0), 0, sg)
39
- d.precision = precision
40
- d
14
+ date = new!(jd_to_ajd(jd, 0, 0), 0, sg)
15
+ date.precision = precision
16
+ date.attributes_set(y,m,d)
17
+ date
41
18
  end
42
19
 
43
20
  class << self; alias_method :new, :civil end
44
-
45
- =begin
46
- Following code is unneccessary, but keeping it as an example
47
- # Return the date as a human-readable string.
48
- #
49
- # The format used is YYYY-MM-DD, YYYY-MM, or YYYY.
50
- def to_s
51
- case
52
- when self.precision.nil?, self.precision >= DateTimePrecision::DAY
53
- format('%.4d-%02d-%02d', year, mon, mday)
54
- when self.precision == DateTimePrecision::MONTH
55
- format('%.4d-%02d', year, mon)
56
- when self.precision == DateTimePrecision::YEAR
57
- format('%.4d', year)
58
- else
59
- '?'
60
- end
61
- end
62
- =end
63
-
64
21
  end
@@ -1,29 +1,13 @@
1
- require 'date_time_precision/lib'
2
- require 'date'
1
+ require 'date_time_precision/patch/1.8.7/date_time'
3
2
 
4
3
  class DateTime < Date
5
- include DateTimePrecision
6
-
7
- MAX_PRECISION = DateTimePrecision::SEC
8
-
9
- def self.parse(str='-4712-01-01T00:00:00+00:00', comp=false, sg=ITALY)
10
- elem = _parse(str, comp)
11
- precision = DateTimePrecision::precision(elem)
12
- dt = new_by_frags(elem, sg)
13
- dt.precision = precision
14
- dt
15
- end
16
4
 
17
5
  def self.civil(y=nil, m=nil, d=nil, h=nil, min=nil, s=nil, of=0, sg=ITALY)
18
- vals = [y,m,d,h,min,s]
19
- precision = DateTimePrecision::precision(vals)
20
- unless vals.all?
21
- vals = vals.compact
22
- vals = vals.concat(NEW_DEFAULTS.slice(vals.length, NEW_DEFAULTS.length - vals.length))
23
- end
24
- y,m,d,h,min,s = vals
6
+ time_args = [y,m,d,h,min,s]
7
+ precision = self.precision(time_args)
8
+ time_args = normalize_new_args(time_args)
25
9
 
26
- unless (jd = _valid_civil?(y, m, d, sg)) && (fr = _valid_time?(h, min, s))
10
+ unless (jd = _valid_civil?(time_args[0], time_args[1], time_args[2], sg)) && (fr = _valid_time?(time_args[3], time_args[4], time_args[5]))
27
11
  raise ArgumentError, 'invalid date'
28
12
  end
29
13
  if String === of
@@ -31,16 +15,9 @@ class DateTime < Date
31
15
  end
32
16
  dt = new!(jd_to_ajd(jd, fr, of), of, sg)
33
17
  dt.precision = precision
18
+ dt.attributes_set(y,m,d,h,min,s)
34
19
  dt
35
20
  end
36
21
 
37
22
  class << self; alias_method :new, :civil end
38
-
39
- def self.strptime(str='-4712-01-01', fmt='%F', sg=ITALY)
40
- elem = _strptime(str, fmt)
41
- precision = DateTimePrecision::precision(elem)
42
- d = new_by_frags(elem, sg)
43
- d.precision = precision
44
- d
45
- end
46
23
  end
@@ -1,37 +1 @@
1
- require 'date_time_precision/lib'
2
- require 'time'
3
-
4
- class Time
5
- include DateTimePrecision
6
-
7
- MAX_PRECISION = DateTimePrecision::FRAC
8
-
9
- class << self
10
- alias_method :mktime_orig, :mktime
11
- def mktime(*args)
12
- time_args = args.shift(Time::MAX_PRECISION)
13
- precision = self.precision(time_args)
14
- time_args = normalize_new_args(time_args)
15
-
16
- t = mktime_orig(*[time_args, args].flatten)
17
- t.precision = precision
18
- t
19
- end
20
-
21
- alias_method :make_time_orig, :make_time
22
- def make_time(*args)
23
- time_args = args.shift(Time::MAX_PRECISION)
24
- precision = self.precision(time_args)
25
- time_args = normalize_new_args(time_args)
26
-
27
- t = make_time_orig(*[time_args, args].flatten)
28
- t.precision = precision
29
- t
30
- end
31
- private :make_time
32
- end
33
-
34
- #def self.strptime(str='-4712-01-01', fmt='%F', sg=Date::ITALY)
35
- # DateTime.strptime(str, fmt, sg).to_time
36
- #end
37
- end
1
+ require 'date_time_precision/patch/1.8.7/time'
@@ -12,7 +12,8 @@ class Date
12
12
  precision = self.precision(args)
13
13
 
14
14
  d = new_orig(*normalize_new_args(args))
15
- d.precision= precision
15
+ d.precision = precision
16
+ d.attributes_set(*args)
16
17
  d
17
18
  end
18
19
 
@@ -31,11 +32,12 @@ class Date
31
32
  args = [y,m,d]
32
33
  precision = self.precision(args)
33
34
 
34
- y,m,d = normalize_new_args(args)
35
+ args = [normalize_new_args(args), sg].flatten
35
36
 
36
- d = civil_orig(y,m,d,sg)
37
- d.precision = precision
38
- d
37
+ date = civil_orig(*args)
38
+ date.precision = precision
39
+ date.attributes_set(y,m,d)
40
+ date
39
41
  end
40
42
 
41
43
  alias_method :strptime_orig, :strptime
@@ -11,7 +11,8 @@ class DateTime < Date
11
11
  def new(*args)
12
12
  precision = self.precision(args)
13
13
  d = new_orig(*normalize_new_args(args))
14
- d.precision= precision
14
+ d.precision = precision
15
+ d.attributes_set(*args)
15
16
  d
16
17
  end
17
18
 
@@ -27,15 +28,13 @@ class DateTime < Date
27
28
 
28
29
  alias_method :civil_orig, :civil
29
30
  def civil(*args)
30
- time_args = args.shift(Time::MAX_PRECISION)
31
- precision = self.precision(time_args)
32
- time_args = normalize_new_args(time_args)
31
+ orig_args = args.shift(Time::MAX_PRECISION)
32
+ precision = self.precision(orig_args)
33
+ time_args = normalize_new_args(orig_args)
33
34
 
34
- t = civil_org(*[time_args, args].flatten)
35
- precision = self.precision(vals)
36
-
37
- dt = civil_orig(*[normalize_new_args(vals) , sg].flatten)
35
+ dt = civil_org(*[time_args, args].flatten)
38
36
  dt.precision = precision
37
+ dt.attributes_set(*orig_args)
39
38
  dt
40
39
  end
41
40
 
@@ -1,33 +1 @@
1
- require 'date_time_precision/lib'
2
- require 'time'
3
-
4
- class Time
5
- include DateTimePrecision
6
-
7
- MAX_PRECISION = DateTimePrecision::FRAC
8
-
9
- class << self
10
- alias_method :mktime_orig, :mktime
11
- def mktime(*args)
12
- time_args = args.shift(Time::MAX_PRECISION)
13
- precision = self.precision(time_args)
14
- time_args = normalize_new_args(time_args)
15
-
16
- t = mktime_orig(*[time_args, args].flatten)
17
- t.precision = precision
18
- t
19
- end
20
-
21
- alias_method :make_time_orig, :make_time
22
- def make_time(*args)
23
- time_args = args.shift(Time::MAX_PRECISION)
24
- precision = self.precision(time_args)
25
- time_args = normalize_new_args(time_args)
26
-
27
- t = make_time_orig(*[time_args, args].flatten)
28
- t.precision = precision
29
- t
30
- end
31
- private :make_time
32
- end
33
- end
1
+ require 'date_time_precision/patch/1.8.7/time'
@@ -1,3 +1,3 @@
1
1
  module DateTimePrecision
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'json'
3
+ require 'securerandom'
3
4
  require 'active_support'
4
5
 
5
6
  require 'date_time_precision'
@@ -33,7 +33,7 @@ describe DateTimePrecision do
33
33
  d.day?.should be_false
34
34
  end
35
35
 
36
- it 'should have day precision when year, month, and day are passed in' do
36
+ it 'has day precision when year, month, and day are passed in' do
37
37
  dt = DateTime.new(1987,10,19)
38
38
  dt.precision.should == DateTimePrecision::DAY
39
39
  dt.year?.should be_true
@@ -42,7 +42,7 @@ describe DateTimePrecision do
42
42
  dt.hour?.should be_false
43
43
  end
44
44
 
45
- it 'should have hour precision' do
45
+ it 'has hour precision' do
46
46
  dt = DateTime.new(1970, 1, 2, 3)
47
47
  dt.precision.should == DateTimePrecision::HOUR
48
48
  dt.year?.should be_true
@@ -51,15 +51,26 @@ describe DateTimePrecision do
51
51
  dt.hour?.should be_true
52
52
  dt.min?.should be_false
53
53
  end
54
+
55
+ it 'tracks which attributes were explicitly set separately from precision' do
56
+ [Date.new(nil, 11, 12), DateTime.new(nil, 10, 11, nil), Time.mktime(nil, 12, 13, nil, 14)].each do |d|
57
+ d.year?.should be_false
58
+ d.month?.should be_true
59
+ d.day?.should be_true
60
+ d.hour?.should be_false
61
+ d.min?.should be_true if d.is_a? Time
62
+ d.precision.should == DateTimePrecision::NONE
63
+ end
64
+ end
54
65
 
55
- it 'should have max precision for fully specified dates/times' do
66
+ it 'has max precision for fully specified dates/times' do
56
67
  # Time.new is an alias for Time.now
57
68
  [Time.new, Time.now, DateTime.now, Date.today].each do |t|
58
69
  t.precision.should == t.class::MAX_PRECISION
59
70
  end
60
71
  end
61
72
 
62
- it 'should accept nil values in the constructor' do
73
+ it 'accepts nil values in the constructor' do
63
74
  Date.new(nil).precision.should == DateTimePrecision::NONE
64
75
  Date.new(2000, nil).precision.should == DateTimePrecision::YEAR
65
76
  DateTime.new(2000, 1, nil).precision.should == DateTimePrecision::MONTH
@@ -163,7 +174,7 @@ describe DateTimePrecision do
163
174
  {
164
175
  :year => 1989,
165
176
  :mon => 3,
166
- :mday => 11
177
+ :day => 11
167
178
  }
168
179
  end
169
180
 
@@ -171,7 +182,7 @@ describe DateTimePrecision do
171
182
  {
172
183
  :year => 1989,
173
184
  :mon => 3,
174
- :mday => 11,
185
+ :day => 11,
175
186
  :hour => 8,
176
187
  :min => 30,
177
188
  :sec => 15,
@@ -196,6 +207,10 @@ describe DateTimePrecision do
196
207
  it 'should convert Time to a hash' do
197
208
  time.to_h.should == time_hash
198
209
  end
210
+
211
+ it 'should skip year if not included' do
212
+ Date.new(nil, 8, 10).to_h.should == {:mon => 8, :day => 10}
213
+ end
199
214
  end
200
215
 
201
216
  context 'Converting to hash with format' do
@@ -241,22 +256,28 @@ describe DateTimePrecision do
241
256
  date.to_h(:short).should == short_date_hash
242
257
  Hash::DATE_FORMATS[:default] = Hash::DATE_FORMATS[:ruby]
243
258
  end
259
+
260
+ it 'should only include fields that were set' do
261
+ Date.new(nil, 3, 8).to_h.should == {:mon => 3, :day => 8}
262
+ DateTime.new(nil, 5, 6, nil, 7).to_h.should == {:mon => 5, :day => 6, :min => 7}
263
+ Time.mktime(nil, 1, nil, 9, nil, 10).to_h.should == {:mon => 1, :hour => 9, :sec => 10}
264
+ end
244
265
  end
245
266
 
246
267
  context 'Converting from hash' do
247
- it 'should convert a hash to a Date' do
268
+ it 'converts a hash to a Date' do
248
269
  date_hash.to_date.should == date
249
270
  end
250
271
 
251
- it 'should convert a hash to a DateTime' do
272
+ it 'converts a hash to a DateTime' do
252
273
  datetime_hash.to_datetime.should == datetime
253
274
  end
254
275
 
255
- it 'should convert a hash to a Time' do
276
+ it 'converts a hash to a Time' do
256
277
  time_hash.to_time.should == time
257
278
  end
258
279
 
259
- it 'should accept flexible keys' do
280
+ it 'accepts flexible keys' do
260
281
  {
261
282
  :y => 1989,
262
283
  :m => 3,
@@ -269,6 +290,23 @@ describe DateTimePrecision do
269
290
  :day => 11
270
291
  }.to_date.should == date
271
292
  end
293
+
294
+ [:date, :datetime, :time].each do |klass|
295
+ it "accepts month and day without year when converting to a #{klass}" do
296
+ date = { :month => 5, :day => 18, :min => 48 }.send("to_#{klass}")
297
+ date.year?.should be_false
298
+ date.month?.should be_true
299
+ date.month.should == 5
300
+ date.day?.should be_true
301
+ date.day.should == 18
302
+ date.hour?.should be_false
303
+
304
+ unless klass == :date
305
+ date.min?.should be_true
306
+ date.min.should == 48
307
+ end
308
+ end
309
+ end
272
310
  end
273
311
  end
274
312
 
metadata CHANGED
@@ -1,112 +1,120 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: date_time_precision
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
5
- prerelease:
4
+ prerelease:
5
+ version: 0.4.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - David Butler
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-26 00:00:00.000000000 Z
12
+ date: 2013-03-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
16
+ version_requirements: !ruby/object:Gem::Requirement
18
17
  requirements:
19
- - - ! '>='
18
+ - - ">="
20
19
  - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
20
+ version: !binary |-
21
+ MA==
25
22
  none: false
23
+ requirement: !ruby/object:Gem::Requirement
26
24
  requirements:
27
- - - ! '>='
25
+ - - ">="
28
26
  - !ruby/object:Gem::Version
29
- version: '0'
27
+ version: !binary |-
28
+ MA==
29
+ none: false
30
+ prerelease: false
31
+ type: :development
30
32
  - !ruby/object:Gem::Dependency
31
33
  name: rspec
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
+ version_requirements: !ruby/object:Gem::Requirement
34
35
  requirements:
35
- - - ! '>='
36
+ - - ">="
36
37
  - !ruby/object:Gem::Version
37
- version: '0'
38
- type: :development
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
38
+ version: !binary |-
39
+ MA==
41
40
  none: false
41
+ requirement: !ruby/object:Gem::Requirement
42
42
  requirements:
43
- - - ! '>='
43
+ - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: !binary |-
46
+ MA==
47
+ none: false
48
+ prerelease: false
49
+ type: :development
46
50
  - !ruby/object:Gem::Dependency
47
51
  name: activesupport
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
52
+ version_requirements: !ruby/object:Gem::Requirement
50
53
  requirements:
51
- - - ! '>='
54
+ - - ">="
52
55
  - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
56
+ version: !binary |-
57
+ MA==
57
58
  none: false
59
+ requirement: !ruby/object:Gem::Requirement
58
60
  requirements:
59
- - - ! '>='
61
+ - - ">="
60
62
  - !ruby/object:Gem::Version
61
- version: '0'
63
+ version: !binary |-
64
+ MA==
65
+ none: false
66
+ prerelease: false
67
+ type: :development
62
68
  - !ruby/object:Gem::Dependency
63
69
  name: json
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
70
+ version_requirements: !ruby/object:Gem::Requirement
66
71
  requirements:
67
- - - ! '>='
72
+ - - ">="
68
73
  - !ruby/object:Gem::Version
69
- version: '0'
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
74
+ version: !binary |-
75
+ MA==
73
76
  none: false
77
+ requirement: !ruby/object:Gem::Requirement
74
78
  requirements:
75
- - - ! '>='
79
+ - - ">="
76
80
  - !ruby/object:Gem::Version
77
- version: '0'
81
+ version: !binary |-
82
+ MA==
83
+ none: false
84
+ prerelease: false
85
+ type: :development
78
86
  - !ruby/object:Gem::Dependency
79
87
  name: virtus
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
88
+ version_requirements: !ruby/object:Gem::Requirement
82
89
  requirements:
83
90
  - - '='
84
91
  - !ruby/object:Gem::Version
85
92
  version: 0.5.4
86
- type: :development
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
93
  none: false
94
+ requirement: !ruby/object:Gem::Requirement
90
95
  requirements:
91
96
  - - '='
92
97
  - !ruby/object:Gem::Version
93
98
  version: 0.5.4
99
+ none: false
100
+ prerelease: false
101
+ type: :development
94
102
  - !ruby/object:Gem::Dependency
95
103
  name: coercible
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
104
+ version_requirements: !ruby/object:Gem::Requirement
98
105
  requirements:
99
106
  - - '='
100
107
  - !ruby/object:Gem::Version
101
108
  version: 0.0.1
102
- type: :development
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
109
  none: false
110
+ requirement: !ruby/object:Gem::Requirement
106
111
  requirements:
107
112
  - - '='
108
113
  - !ruby/object:Gem::Version
109
114
  version: 0.0.1
115
+ none: false
116
+ prerelease: false
117
+ type: :development
110
118
  description: Patches Date, Time, and DateTime ruby classes to keep track of precision
111
119
  email:
112
120
  - dwbutler@ucla.edu
@@ -114,8 +122,8 @@ executables: []
114
122
  extensions: []
115
123
  extra_rdoc_files: []
116
124
  files:
117
- - .gitignore
118
- - .travis.yml
125
+ - ".gitignore"
126
+ - ".travis.yml"
119
127
  - Gemfile
120
128
  - LICENSE
121
129
  - README
@@ -149,32 +157,34 @@ files:
149
157
  - spec/spec_helper.rb
150
158
  homepage: http://github.com/Spokeo/date_time_precision
151
159
  licenses: []
152
- post_install_message:
160
+ post_install_message:
153
161
  rdoc_options: []
154
162
  require_paths:
155
163
  - lib
156
164
  required_ruby_version: !ruby/object:Gem::Requirement
157
- none: false
158
165
  requirements:
159
- - - ! '>='
166
+ - - ">="
160
167
  - !ruby/object:Gem::Version
161
- version: '0'
162
168
  segments:
163
169
  - 0
164
- hash: 1472346425061426600
165
- required_rubygems_version: !ruby/object:Gem::Requirement
170
+ hash: 2
171
+ version: !binary |-
172
+ MA==
166
173
  none: false
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
175
  requirements:
168
- - - ! '>='
176
+ - - ">="
169
177
  - !ruby/object:Gem::Version
170
- version: '0'
171
178
  segments:
172
179
  - 0
173
- hash: 1472346425061426600
180
+ hash: 2
181
+ version: !binary |-
182
+ MA==
183
+ none: false
174
184
  requirements: []
175
- rubyforge_project:
176
- rubygems_version: 1.8.25
177
- signing_key:
185
+ rubyforge_project:
186
+ rubygems_version: 1.8.24
187
+ signing_key:
178
188
  specification_version: 3
179
189
  summary: Patches Date, Time, and DateTime ruby classes to keep track of precision
180
190
  test_files: