date_time_precision 0.3.2 → 0.4.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 +12 -3
- data/lib/date_time_precision/format/hash.rb +1 -1
- data/lib/date_time_precision/lib.rb +47 -17
- data/lib/date_time_precision/patch/1.8.7/date.rb +11 -13
- data/lib/date_time_precision/patch/1.8.7/date_time.rb +7 -10
- data/lib/date_time_precision/patch/1.8.7/time.rb +10 -8
- data/lib/date_time_precision/patch/1.9.2/date.rb +10 -53
- data/lib/date_time_precision/patch/1.9.2/date_time.rb +6 -29
- data/lib/date_time_precision/patch/1.9.2/time.rb +1 -37
- data/lib/date_time_precision/patch/1.9.3/date.rb +7 -5
- data/lib/date_time_precision/patch/1.9.3/date_time.rb +7 -8
- data/lib/date_time_precision/patch/1.9.3/time.rb +1 -33
- data/lib/date_time_precision/version.rb +1 -1
- data/spec/date_time_precision/active_support_spec.rb +1 -0
- data/spec/date_time_precision/date_time_precision_spec.rb +48 -10
- metadata +74 -64
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
|
24
|
+
d.precision # => DateTimePrecision::YEAR
|
25
25
|
|
26
26
|
t = Time::parse("2001-05")
|
27
|
-
t.precision
|
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
|
|
@@ -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
|
-
:
|
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.
|
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
|
-
|
120
|
-
args = args.
|
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
|
-
|
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 :
|
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
|
-
|
27
|
-
precision =
|
28
|
-
|
29
|
-
|
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?(
|
31
|
+
unless jd = valid_civil?(*args)
|
35
32
|
raise ArgumentError, 'invalid date'
|
36
33
|
end
|
37
34
|
|
38
|
-
|
39
|
-
|
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
|
-
|
19
|
-
precision =
|
20
|
-
|
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?(
|
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
|
-
|
13
|
-
precision = self.precision(
|
14
|
-
time_args = normalize_new_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
|
-
|
24
|
-
precision = self.precision(
|
25
|
-
time_args = normalize_new_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/
|
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
|
-
|
27
|
-
precision =
|
28
|
-
|
29
|
-
|
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?(
|
10
|
+
unless jd = _valid_civil?(*[args, sg].flatten)
|
35
11
|
raise ArgumentError, 'invalid date'
|
36
12
|
end
|
37
13
|
|
38
|
-
|
39
|
-
|
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/
|
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
|
-
|
19
|
-
precision =
|
20
|
-
|
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?(
|
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/
|
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
|
-
|
35
|
+
args = [normalize_new_args(args), sg].flatten
|
35
36
|
|
36
|
-
|
37
|
-
|
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
|
-
|
31
|
-
precision = self.precision(
|
32
|
-
time_args = normalize_new_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
|
-
|
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/
|
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'
|
@@ -33,7 +33,7 @@ describe DateTimePrecision do
|
|
33
33
|
d.day?.should be_false
|
34
34
|
end
|
35
35
|
|
36
|
-
it '
|
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 '
|
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 '
|
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 '
|
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
|
-
:
|
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
|
-
:
|
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 '
|
268
|
+
it 'converts a hash to a Date' do
|
248
269
|
date_hash.to_date.should == date
|
249
270
|
end
|
250
271
|
|
251
|
-
it '
|
272
|
+
it 'converts a hash to a DateTime' do
|
252
273
|
datetime_hash.to_datetime.should == datetime
|
253
274
|
end
|
254
275
|
|
255
|
-
it '
|
276
|
+
it 'converts a hash to a Time' do
|
256
277
|
time_hash.to_time.should == time
|
257
278
|
end
|
258
279
|
|
259
|
-
it '
|
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
|
-
|
5
|
-
|
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-
|
12
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
|
17
|
-
none: false
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
|
-
- -
|
18
|
+
- - ">="
|
20
19
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
-
|
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:
|
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
|
-
|
33
|
-
none: false
|
34
|
+
version_requirements: !ruby/object:Gem::Requirement
|
34
35
|
requirements:
|
35
|
-
- -
|
36
|
+
- - ">="
|
36
37
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
38
|
-
|
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:
|
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
|
-
|
49
|
-
none: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
53
|
requirements:
|
51
|
-
- -
|
54
|
+
- - ">="
|
52
55
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
54
|
-
|
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:
|
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
|
-
|
65
|
-
none: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
71
|
requirements:
|
67
|
-
- -
|
72
|
+
- - ">="
|
68
73
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
70
|
-
|
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:
|
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
|
-
|
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
|
-
|
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:
|
165
|
-
|
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:
|
180
|
+
hash: 2
|
181
|
+
version: !binary |-
|
182
|
+
MA==
|
183
|
+
none: false
|
174
184
|
requirements: []
|
175
|
-
rubyforge_project:
|
176
|
-
rubygems_version: 1.8.
|
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:
|