timeliness 0.1.1 → 0.2.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/CHANGELOG.rdoc +7 -0
- data/README.rdoc +62 -39
- data/lib/timeliness.rb +10 -3
- data/lib/timeliness/format_set.rb +5 -1
- data/lib/timeliness/formats.rb +2 -1
- data/lib/timeliness/parser.rb +34 -21
- data/lib/timeliness/version.rb +1 -1
- data/spec/timeliness/format_set_spec.rb +10 -6
- data/spec/timeliness/formats_spec.rb +12 -11
- data/spec/timeliness/parser_spec.rb +42 -17
- data/timeliness.gemspec +2 -2
- metadata +5 -5
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
= 0.2.0 - 2010-10-27
|
2
|
+
* Allow a lambda for date_for_time_type which is evaluated on parse
|
3
|
+
* Return the offset or zone in array from _parse
|
4
|
+
* Give a nicer error message if use a zone and ActiveSupport is not loaded.
|
5
|
+
* Removed some aliases used in validates_timeliness and are no longer needed.
|
6
|
+
* Some minor spec fixes
|
7
|
+
|
1
8
|
= 0.1.1 - 2010-10-14
|
2
9
|
* Alias for validates_timeliness compatibility
|
3
10
|
* Tiny cleanup
|
data/README.rdoc
CHANGED
@@ -14,9 +14,11 @@ Date/time parser for Ruby with the following features:
|
|
14
14
|
* I18n support (for months), if I18n gem loaded.
|
15
15
|
* Fewer WTFs than Time/Date parse method.
|
16
16
|
* Has no dependencies.
|
17
|
+
* Works with Ruby MRI 1.8.*, 1.9.2, Rubinius
|
17
18
|
|
18
19
|
Extracted from my {validates_timeliness gem}[http://github.com/adzap/validates_timeliness], it has been rewritten cleaner and much faster. It's most suitable for when
|
19
|
-
you need to control the parsing behaviour. It's faster than the Time/Date class parse methods, so it
|
20
|
+
you need to control the parsing behaviour. It's faster than the Time/Date class parse methods, so it
|
21
|
+
has general appeal.
|
20
22
|
|
21
23
|
|
22
24
|
== Usage
|
@@ -27,16 +29,11 @@ The simplest example is just a straight forward string parse:
|
|
27
29
|
Timeliness.parse('2010-09-08') #=> Wed Sep 08 00:00:00 1000 2010
|
28
30
|
Timeliness.parse('12:13:14') #=> Sat Jan 01 12:13:14 1100 2000
|
29
31
|
|
30
|
-
Notice a time only string will return with a date value. The date value can be configured globally with
|
31
|
-
this setting:
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
or specified with :now option:
|
33
|
+
=== Specify a Type
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
You can also provide a type which will tell the parser that you are only interested in the part of the value for that type.
|
35
|
+
You can provide a type which will tell the parser that you are only interested in the part of
|
36
|
+
the value for that type.
|
40
37
|
|
41
38
|
Timeliness.parse('2010-09-08 12:13:14', :date) #=> Wed Sep 08 00:00:00 1000 2010
|
42
39
|
Timeliness.parse('2010-09-08 12:13:14', :time) #=> Sat Jan 01 12:13:14 1100 2000
|
@@ -48,15 +45,35 @@ Now let's get strict. Pass the :strict option with true and things get finicky
|
|
48
45
|
Timeliness.parse('2010-09-08 12:13:14', :time, :strict => true) #=> nil
|
49
46
|
Timeliness.parse('2010-09-08 12:13:14', :datetime, :strict => true) #=> Wed Sep 08 12:13:14 1000 2010 i.e. the whole string is used
|
50
47
|
|
51
|
-
The date and time strings are not accepted for a datetime type. The strict option without a type is
|
48
|
+
The date and time strings are not accepted for a datetime type. The strict option without a type is
|
49
|
+
ignored.
|
50
|
+
|
51
|
+
|
52
|
+
=== Specify the Current Date
|
53
|
+
|
54
|
+
Notice a time only string will return with a date value. The date value can be configured globally
|
55
|
+
with this setting:
|
56
|
+
|
57
|
+
Timeliness.date_for_time_type = [2010, 1, 1]
|
58
|
+
|
59
|
+
or using a lambda thats evaluated when parsed
|
52
60
|
|
53
|
-
|
54
|
-
|
61
|
+
Timeliness.date_for_time_type = lambda { Time.now }
|
62
|
+
|
63
|
+
It can also be specified with :now option:
|
64
|
+
|
65
|
+
Timeliness.parse('12:13:14', :now => Time.mktime(2010,9,8)) #=> Wed Sep 08 12:13:14 1000 2010
|
66
|
+
|
67
|
+
|
68
|
+
=== Timezone
|
69
|
+
|
70
|
+
To control what zone the time object is returned in, you have two options. Firstly you can set the
|
71
|
+
default zone. Below is the list of options with their effective time creation method call
|
55
72
|
|
56
73
|
Timeliness.default_timezone = :local # Time.local(...)
|
57
74
|
Timeliness.default_timezone = :utc # Time.utc(...)
|
58
|
-
Timeliness.default_timezone = :current # Time.zone.local(...)
|
59
|
-
Timeliness.default_timezone = 'Melbourne' # Time.use_zone('Melbourne') { Time.zone.local(...) }
|
75
|
+
Timeliness.default_timezone = :current # Time.zone.local(...). Use current zone.
|
76
|
+
Timeliness.default_timezone = 'Melbourne' # Time.use_zone('Melbourne') { Time.zone.local(...) }. Doesn't change Time.zone.
|
60
77
|
|
61
78
|
The last two options require that you have ActiveSupport timezone extension loaded.
|
62
79
|
|
@@ -69,25 +86,32 @@ You can also use the :zone option to control it for a single parse call:
|
|
69
86
|
|
70
87
|
Remember, you must have ActiveSupport timezone extension loaded to use the last two examples.
|
71
88
|
|
89
|
+
|
90
|
+
=== Restrict to Format
|
91
|
+
|
72
92
|
To get super finicky, you can restrict the parsing to a single format with the :format option
|
73
93
|
|
74
94
|
Timeliness.parse('2010-09-08 12:13:14', :format => 'yyyy-mm-dd hh:nn:ss') #=> Wed Sep 08 12:13:14 UTC 2010
|
75
95
|
Timeliness.parse('08/09/2010 12:13:14', :format => 'yyyy-mm-dd hh:nn:ss') #=> nil
|
76
96
|
|
97
|
+
|
98
|
+
=== Raw Parsed Values
|
99
|
+
|
77
100
|
If you would like to get the raw array of values before the time object is created, you can with
|
78
101
|
|
79
|
-
Timeliness._parse('2010-09-08 12:13:14') # => [2010, 9, 8, 12, 13, 14, nil]
|
102
|
+
Timeliness._parse('2010-09-08 12:13:14') # => [2010, 9, 8, 12, 13, 14, nil, nil]
|
80
103
|
|
81
|
-
The last
|
104
|
+
The last two nils are for the empty value of microseconds, and timezone or offset.
|
82
105
|
|
83
106
|
|
84
107
|
== Formats
|
85
108
|
|
86
|
-
The gem has default formats included which can be easily added to using the format syntax. Also
|
87
|
-
removed so that they are no longer considered valid.
|
109
|
+
The gem has default formats included which can be easily added to using the format syntax. Also
|
110
|
+
formats can be easily removed so that they are no longer considered valid.
|
88
111
|
|
89
|
-
Below are the default formats. If you think they are easy to read then you will be happy to know
|
90
|
-
format syntax you can use to define your own. No complex regular
|
112
|
+
Below are the default formats. If you think they are easy to read then you will be happy to know
|
113
|
+
that is exactly the same format syntax you can use to define your own. No complex regular
|
114
|
+
expressions are needed.
|
91
115
|
|
92
116
|
|
93
117
|
=== Datetime formats
|
@@ -164,7 +188,8 @@ Here is what each format token means:
|
|
164
188
|
ddd = Day name of 3 to 9 letters (e.g. Wed or Wednesday)
|
165
189
|
u = microseconds matches 1 to 3 digits
|
166
190
|
|
167
|
-
All other characters are considered literal. For the technically minded, these formats are compiled
|
191
|
+
All other characters are considered literal. For the technically minded, these formats are compiled
|
192
|
+
into a single regular expression
|
168
193
|
|
169
194
|
To see all defined formats look at the {source code}[http://github.com/adzap/timeliness/tree/master/lib/timeliness/formats.rb].
|
170
195
|
|
@@ -173,9 +198,9 @@ To see all defined formats look at the {source code}[http://github.com/adzap/tim
|
|
173
198
|
|
174
199
|
=== US/Euro Formats
|
175
200
|
|
176
|
-
The perennial problem for non-US developers or applications not primarily for the
|
177
|
-
|
178
|
-
|
201
|
+
The perennial problem for non-US developers or applications not primarily for the US, is the US date
|
202
|
+
format of m/d/yy. This is ambiguous with the European format of d/m/yy. By default the gem uses the
|
203
|
+
US formats as this is the Ruby default
|
179
204
|
when it does date interpretation.
|
180
205
|
|
181
206
|
To switch to using the European (or Rest of The World) formats use this setting
|
@@ -191,8 +216,8 @@ You can switch back to US formats with
|
|
191
216
|
|
192
217
|
=== Customising Formats
|
193
218
|
|
194
|
-
Sometimes you may not want certain formats to be valid. You can remove formats for each type and
|
195
|
-
|
219
|
+
Sometimes you may not want certain formats to be valid. You can remove formats for each type and the
|
220
|
+
parser will then not consider that a valid format. To remove a format
|
196
221
|
|
197
222
|
Timeliness.remove_formats(:date, 'm\d\yy')
|
198
223
|
|
@@ -202,27 +227,25 @@ Adding new formats is also simple
|
|
202
227
|
|
203
228
|
Now "10 o'clock" will be a valid value.
|
204
229
|
|
205
|
-
You can embed regular expressions in the format but no guarantees that it will
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
datetime for an example of an embedded regular expression.
|
230
|
+
You can embed regular expressions in the format but no guarantees that it will remain intact. If
|
231
|
+
you avoid the use of any token characters, and regexp dots or backslashes as special characters in
|
232
|
+
the regexp, it may work as expected. For special characters use POSIX character classes for safety.
|
233
|
+
See the ISO 8601 datetime for an example of an embedded regular expression.
|
210
234
|
|
211
|
-
Because formats are evaluated in order, adding a format which may be ambiguous
|
212
|
-
|
213
|
-
|
214
|
-
before option like so
|
235
|
+
Because formats are evaluated in order, adding a format which may be ambiguous with an existing
|
236
|
+
format, will mean your format is ignored. If you need to make your new format higher precedence than
|
237
|
+
an existing format, you can include the before option like so
|
215
238
|
|
216
239
|
Timeliness.add_formats(:time, 'ss:nn:hh', :before => 'hh:nn:ss')
|
217
240
|
|
218
|
-
Now a time of '59:30:23' will be interpreted as 11:30:59 pm. This option saves
|
219
|
-
|
241
|
+
Now a time of '59:30:23' will be interpreted as 11:30:59 pm. This option saves you adding a new one
|
242
|
+
and deleting an old one to get it to work.
|
220
243
|
|
221
244
|
|
222
245
|
=== Ambiguous Year
|
223
246
|
|
224
|
-
When dealing with 2 digit year values, by default a year is interpreted as being
|
225
|
-
|
247
|
+
When dealing with 2 digit year values, by default a year is interpreted as being in the last century
|
248
|
+
when at or above 30. You can customize this however
|
226
249
|
|
227
250
|
Timeliness.ambiguous_year_threshold = 20
|
228
251
|
|
data/lib/timeliness.rb
CHANGED
@@ -12,10 +12,7 @@ module Timeliness
|
|
12
12
|
extend Forwardable
|
13
13
|
def_delegators Parser, :parse, :_parse
|
14
14
|
def_delegators Formats, :add_formats, :remove_formats, :use_us_formats, :use_euro_formats
|
15
|
-
|
16
15
|
attr_accessor :default_timezone, :date_for_time_type, :ambiguous_year_threshold
|
17
|
-
|
18
|
-
alias :dummy_date_for_time_type :date_for_time_type
|
19
16
|
end
|
20
17
|
|
21
18
|
# Default timezone. Options:
|
@@ -31,6 +28,16 @@ module Timeliness
|
|
31
28
|
# Set the default date part for a time type values.
|
32
29
|
@date_for_time_type = [ 2000, 1, 1 ]
|
33
30
|
|
31
|
+
def self.date_for_time_type
|
32
|
+
case @date_for_time_type
|
33
|
+
when Array
|
34
|
+
@date_for_time_type
|
35
|
+
when Proc
|
36
|
+
v = @date_for_time_type.call
|
37
|
+
[v.year, v.month, v.day]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
34
41
|
# Set the threshold value for a two digit year to be considered last century
|
35
42
|
#
|
36
43
|
# Default: 30
|
@@ -48,7 +48,7 @@ module Timeliness
|
|
48
48
|
# values placed in the position defined by the component.
|
49
49
|
#
|
50
50
|
def define_format_method(name, components)
|
51
|
-
values = [nil] *
|
51
|
+
values = [nil] * 8
|
52
52
|
components.each do |component|
|
53
53
|
position, code = *Formats.format_components[component]
|
54
54
|
values[position] = code || "#{component}.to_i" if position
|
@@ -66,6 +66,10 @@ module Timeliness
|
|
66
66
|
@formats = formats
|
67
67
|
end
|
68
68
|
|
69
|
+
# Compiles the formats into one big regexp. Stores the index of where
|
70
|
+
# each format's capture values begin in the match data. Each individual
|
71
|
+
# format regpexp is also stored for use with the parse :format option.
|
72
|
+
#
|
69
73
|
def compile!
|
70
74
|
regexp_string = ''
|
71
75
|
@format_regexps = {}
|
data/lib/timeliness/formats.rb
CHANGED
@@ -100,7 +100,7 @@ module Timeliness
|
|
100
100
|
'u' => [ '\d{1,6}', :usec ],
|
101
101
|
'ampm' => [ '[aApP]\.?[mM]\.?', :meridian ],
|
102
102
|
'zo' => [ '[+-]\d{2}:?\d{2}', :offset ],
|
103
|
-
'tz' => [ '[A-Z]{1,4}' ],
|
103
|
+
'tz' => [ '[A-Z]{1,4}', :zone ],
|
104
104
|
'_' => [ '\s?' ]
|
105
105
|
}
|
106
106
|
|
@@ -122,6 +122,7 @@ module Timeliness
|
|
122
122
|
:sec => [ 5 ],
|
123
123
|
:usec => [ 6, 'microseconds(usec)'],
|
124
124
|
:offset => [ 7, 'offset_in_seconds(offset)'],
|
125
|
+
:zone => [ 7, 'zone'],
|
125
126
|
:meridian => [ nil ]
|
126
127
|
}
|
127
128
|
|
data/lib/timeliness/parser.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Timeliness
|
2
2
|
module Parser
|
3
|
+
class MissingTimezoneSupport < StandardError; end
|
3
4
|
|
4
5
|
class << self
|
5
6
|
|
@@ -12,18 +13,11 @@ module Timeliness
|
|
12
13
|
time_array = _parse(value, type, options)
|
13
14
|
return nil if time_array.nil?
|
14
15
|
|
15
|
-
|
16
|
-
when :date
|
17
|
-
time_array[3..7] = nil
|
18
|
-
when :time
|
19
|
-
time_array[0..2] = current_date(options)
|
20
|
-
when nil
|
21
|
-
dummy_date = current_date(options)
|
22
|
-
time_array[0] ||= dummy_date[0]
|
23
|
-
time_array[1] ||= dummy_date[1]
|
24
|
-
time_array[2] ||= dummy_date[2]
|
25
|
-
end
|
16
|
+
override_values_by_type(time_array, type, options) unless type == :datetime
|
26
17
|
make_time(time_array[0..6], options[:zone])
|
18
|
+
rescue NoMethodError => ex
|
19
|
+
raise ex unless ex.message =~ /zone/
|
20
|
+
raise MissingTimezoneSupport, "ActiveSupport must be loaded to use timezones other than :utc and :local."
|
27
21
|
end
|
28
22
|
|
29
23
|
def make_time(time_array, zone=nil)
|
@@ -57,21 +51,40 @@ module Timeliness
|
|
57
51
|
|
58
52
|
private
|
59
53
|
|
54
|
+
def override_values_by_type(values, type, options)
|
55
|
+
case type
|
56
|
+
when :date
|
57
|
+
values[3..7] = nil
|
58
|
+
when :time
|
59
|
+
values[0..2] = current_date(options)
|
60
|
+
when nil
|
61
|
+
dummy_date = current_date(options)
|
62
|
+
values[0] ||= dummy_date[0]
|
63
|
+
values[1] ||= dummy_date[1]
|
64
|
+
values[2] ||= dummy_date[2]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
60
68
|
def current_date(options)
|
61
69
|
now = if options[:now]
|
62
70
|
options[:now]
|
63
71
|
elsif options[:zone]
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
+
current_time_in_zone(options[:zone])
|
73
|
+
else
|
74
|
+
Timeliness.date_for_time_type
|
75
|
+
end
|
76
|
+
now.is_a?(Array) ? now[0..2] : [now.year, now.month, now.day]
|
77
|
+
end
|
78
|
+
|
79
|
+
def current_time_in_zone(zone)
|
80
|
+
case zone
|
81
|
+
when :utc, :local
|
82
|
+
Time.now.send("get#{zone}")
|
83
|
+
when :current
|
84
|
+
Time.current
|
85
|
+
else
|
86
|
+
Time.use_zone(zone) { Time.current }
|
72
87
|
end
|
73
|
-
now ||= Timeliness.date_for_time_type
|
74
|
-
now.is_a?(Array) ? now[0..2] : Array(now).reverse[4..6]
|
75
88
|
end
|
76
89
|
|
77
90
|
# Taken from ActiveSupport and simplified
|
data/lib/timeliness/version.rb
CHANGED
@@ -3,32 +3,36 @@ require 'spec_helper'
|
|
3
3
|
describe Timeliness::FormatSet do
|
4
4
|
context ".define_format_method" do
|
5
5
|
it "should define method which outputs date array with values in correct order" do
|
6
|
-
define_method_for('yyyy-mm-dd').call('2000', '1', '2').should == [2000,1,2,nil,nil,nil,nil]
|
6
|
+
define_method_for('yyyy-mm-dd').call('2000', '1', '2').should == [2000,1,2,nil,nil,nil,nil,nil]
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should define method which outputs date array from format with different order" do
|
10
|
-
define_method_for('dd/mm/yyyy').call('2', '1', '2000').should == [2000,1,2,nil,nil,nil,nil]
|
10
|
+
define_method_for('dd/mm/yyyy').call('2', '1', '2000').should == [2000,1,2,nil,nil,nil,nil,nil]
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should define method which outputs time array" do
|
14
|
-
define_method_for('hh:nn:ss').call('01', '02', '03').should == [nil,nil,nil,1,2,3,nil]
|
14
|
+
define_method_for('hh:nn:ss').call('01', '02', '03').should == [nil,nil,nil,1,2,3,nil,nil]
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should define method which outputs time array with meridian 'pm' adjusted hour" do
|
18
|
-
define_method_for('hh:nn:ss ampm').call('01', '02', '03', 'pm').should == [nil,nil,nil,13,2,3,nil]
|
18
|
+
define_method_for('hh:nn:ss ampm').call('01', '02', '03', 'pm').should == [nil,nil,nil,13,2,3,nil,nil]
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should define method which outputs time array with meridian 'am' unadjusted hour" do
|
22
|
-
define_method_for('hh:nn:ss ampm').call('01', '02', '03', 'am').should == [nil,nil,nil,1,2,3,nil]
|
22
|
+
define_method_for('hh:nn:ss ampm').call('01', '02', '03', 'am').should == [nil,nil,nil,1,2,3,nil,nil]
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should define method which outputs time array with microseconds" do
|
26
|
-
define_method_for('hh:nn:ss.u').call('01', '02', '03', '99').should == [nil,nil,nil,1,2,3,990000]
|
26
|
+
define_method_for('hh:nn:ss.u').call('01', '02', '03', '99').should == [nil,nil,nil,1,2,3,990000,nil]
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should define method which outputs datetime array with zone offset" do
|
30
30
|
define_method_for('yyyy-mm-dd hh:nn:ss.u zo').call('2001', '02', '03', '04', '05', '06', '99', '+10:00').should == [2001,2,3,4,5,6,990000,36000]
|
31
31
|
end
|
32
|
+
|
33
|
+
it "should define method which outputs datetime array with timezone string" do
|
34
|
+
define_method_for('yyyy-mm-dd hh:nn:ss.u tz').call('2001', '02', '03', '04', '05', '06', '99', 'EST').should == [2001,2,3,4,5,6,990000,'EST']
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
context "compiled regexp" do
|
@@ -26,7 +26,7 @@ describe Timeliness::Formats do
|
|
26
26
|
it "should add new format with higher precedence" do
|
27
27
|
formats.add_formats(:time, "ss:hh:nn", :before => 'hh:nn:ss')
|
28
28
|
time_array = parser._parse('59:23:58', :time)
|
29
|
-
time_array.should == [nil,nil,nil,23,58,59,nil]
|
29
|
+
time_array.should == [nil,nil,nil,23,58,59,nil,nil]
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should raise error if :before format does not exist" do
|
@@ -45,17 +45,18 @@ describe Timeliness::Formats do
|
|
45
45
|
@default_formats = formats.time_formats.dup
|
46
46
|
end
|
47
47
|
|
48
|
-
it "should remove format from
|
48
|
+
it "should remove a single format from the formats array for type" do
|
49
49
|
formats.remove_formats(:time, 'h.nn_ampm')
|
50
|
-
formats.time_formats.should_not include(
|
50
|
+
formats.time_formats.should_not include('h.nn_ampm')
|
51
51
|
end
|
52
52
|
|
53
|
-
it "should remove multiple formats from
|
54
|
-
formats.remove_formats(:time, 'h.nn_ampm')
|
55
|
-
formats.time_formats.should_not include(
|
53
|
+
it "should remove multiple formats from formats array for type" do
|
54
|
+
formats.remove_formats(:time, 'h:nn', 'h.nn_ampm')
|
55
|
+
formats.time_formats.should_not include('h:nn')
|
56
|
+
formats.time_formats.should_not include('h.nn_ampm')
|
56
57
|
end
|
57
58
|
|
58
|
-
it "should
|
59
|
+
it "should prevent parsing of removed format" do
|
59
60
|
should_parse('2.12am', :time)
|
60
61
|
formats.remove_formats(:time, 'h.nn_ampm')
|
61
62
|
should_not_parse('2.12am', :time)
|
@@ -73,9 +74,9 @@ describe Timeliness::Formats do
|
|
73
74
|
|
74
75
|
context "use_euro_formats" do
|
75
76
|
it "should allow ambiguous date to be parsed as European format" do
|
76
|
-
parser._parse('01/02/2000', :date).should == [2000,1,2,nil,nil,nil,nil]
|
77
|
+
parser._parse('01/02/2000', :date).should == [2000,1,2,nil,nil,nil,nil,nil]
|
77
78
|
formats.use_euro_formats
|
78
|
-
parser._parse('01/02/2000', :date).should == [2000,2,1,nil,nil,nil,nil]
|
79
|
+
parser._parse('01/02/2000', :date).should == [2000,2,1,nil,nil,nil,nil,nil]
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -85,9 +86,9 @@ describe Timeliness::Formats do
|
|
85
86
|
end
|
86
87
|
|
87
88
|
it "should allow ambiguous date to be parsed as European format" do
|
88
|
-
parser._parse('01/02/2000', :date).should == [2000,2,1,nil,nil,nil,nil]
|
89
|
+
parser._parse('01/02/2000', :date).should == [2000,2,1,nil,nil,nil,nil,nil]
|
89
90
|
formats.use_us_formats
|
90
|
-
parser._parse('01/02/2000', :date).should == [2000,1,2,nil,nil,nil,nil]
|
91
|
+
parser._parse('01/02/2000', :date).should == [2000,1,2,nil,nil,nil,nil,nil]
|
91
92
|
end
|
92
93
|
end
|
93
94
|
end
|
@@ -71,11 +71,36 @@ describe Timeliness::Parser do
|
|
71
71
|
time.utc_offset.should == 1.hour
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
context "without ActiveSupport loaded" do
|
76
|
+
it 'should output message' do
|
77
|
+
lambda {
|
78
|
+
Time.should_receive(:use_zone).and_raise(NoMethodError.new("undefined method `zone' for Time:Class"))
|
79
|
+
time = parse("2000-06-01 12:13:14", :datetime, :zone => 'London')
|
80
|
+
}.should raise_error(Timeliness::Parser::MissingTimezoneSupport)
|
81
|
+
end
|
82
|
+
end
|
74
83
|
end
|
75
84
|
|
76
85
|
describe "for time type" do
|
77
|
-
|
78
|
-
|
86
|
+
context "with date from date_for_time_type" do
|
87
|
+
before do
|
88
|
+
@original = Timeliness.date_for_time_type
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should return date array' do
|
92
|
+
Timeliness.date_for_time_type = [2010,1,1]
|
93
|
+
parse('12:13:14', :time).should == Time.local(2010,1,1,12,13,14)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should return date array evaluated lambda' do
|
97
|
+
Timeliness.date_for_time_type = lambda { Time.local(2010,2,1) }
|
98
|
+
parse('12:13:14', :time).should == Time.local(2010,2,1,12,13,14)
|
99
|
+
end
|
100
|
+
|
101
|
+
after do
|
102
|
+
Timeliness.date_for_time_type = @original
|
103
|
+
end
|
79
104
|
end
|
80
105
|
|
81
106
|
context "with :now option" do
|
@@ -107,54 +132,54 @@ describe Timeliness::Parser do
|
|
107
132
|
context "with type" do
|
108
133
|
it "should return date array from date string" do
|
109
134
|
time_array = parser._parse('2000-02-01', :date)
|
110
|
-
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
135
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil,nil]
|
111
136
|
end
|
112
137
|
|
113
138
|
it "should return time array from time string" do
|
114
139
|
time_array = parser._parse('12:13:14', :time)
|
115
|
-
time_array.should == [nil,nil,nil,12,13,14,nil]
|
140
|
+
time_array.should == [nil,nil,nil,12,13,14,nil,nil]
|
116
141
|
end
|
117
142
|
|
118
143
|
it "should return datetime array from datetime string" do
|
119
144
|
time_array = parser._parse('2000-02-01 12:13:14', :datetime)
|
120
|
-
time_array.should == [2000,2,1,12,13,14,nil]
|
145
|
+
time_array.should == [2000,2,1,12,13,14,nil,nil]
|
121
146
|
end
|
122
147
|
|
123
148
|
it "should return date array from date string when type is datetime" do
|
124
149
|
time_array = parser._parse('2000-02-01', :datetime)
|
125
|
-
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
150
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil,nil]
|
126
151
|
end
|
127
152
|
|
128
153
|
it "should return datetime array from datetime string when type is date" do
|
129
154
|
time_array = parser._parse('2000-02-01 12:13:14', :date)
|
130
|
-
time_array.should == [2000,2,1,12,13,14,nil]
|
155
|
+
time_array.should == [2000,2,1,12,13,14,nil,nil]
|
131
156
|
end
|
132
157
|
end
|
133
158
|
|
134
159
|
context "with no type" do
|
135
160
|
it "should return date array from date string" do
|
136
161
|
time_array = parser._parse('2000-02-01')
|
137
|
-
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
162
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil,nil]
|
138
163
|
end
|
139
164
|
|
140
165
|
it "should return time array from time string" do
|
141
166
|
time_array = parser._parse('12:13:14', :time)
|
142
|
-
time_array.should == [nil,nil,nil,12,13,14,nil]
|
167
|
+
time_array.should == [nil,nil,nil,12,13,14,nil,nil]
|
143
168
|
end
|
144
169
|
|
145
170
|
it "should return datetime array from datetime string" do
|
146
171
|
time_array = parser._parse('2000-02-01 12:13:14')
|
147
|
-
time_array.should == [2000,2,1,12,13,14,nil]
|
172
|
+
time_array.should == [2000,2,1,12,13,14,nil,nil]
|
148
173
|
end
|
149
174
|
|
150
175
|
it "should return date array from date string when type is datetime" do
|
151
176
|
time_array = parser._parse('2000-02-01')
|
152
|
-
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
177
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil,nil]
|
153
178
|
end
|
154
179
|
|
155
180
|
it "should return datetime array from datetime string when type is date" do
|
156
181
|
time_array = parser._parse('2000-02-01 12:13:14')
|
157
|
-
time_array.should == [2000,2,1,12,13,14,nil]
|
182
|
+
time_array.should == [2000,2,1,12,13,14,nil,nil]
|
158
183
|
end
|
159
184
|
end
|
160
185
|
|
@@ -205,7 +230,7 @@ describe Timeliness::Parser do
|
|
205
230
|
context "with :format option" do
|
206
231
|
it "should return values if string matches specified format" do
|
207
232
|
time_array = parser._parse('2000-02-01 12:13:14', :datetime, :format => 'yyyy-mm-dd hh:nn:ss')
|
208
|
-
time_array.should == [2000,2,1,12,13,14,nil]
|
233
|
+
time_array.should == [2000,2,1,12,13,14,nil,nil]
|
209
234
|
end
|
210
235
|
|
211
236
|
it "should return nil if string does not match specified format" do
|
@@ -217,21 +242,21 @@ describe Timeliness::Parser do
|
|
217
242
|
context "date with ambiguous year" do
|
218
243
|
it "should return year in current century if year below threshold" do
|
219
244
|
time_array = parser._parse('01-02-29', :date)
|
220
|
-
time_array.should == [2029,2,1,nil,nil,nil,nil]
|
245
|
+
time_array.should == [2029,2,1,nil,nil,nil,nil,nil]
|
221
246
|
end
|
222
247
|
|
223
248
|
it "should return year in last century if year at or above threshold" do
|
224
249
|
time_array = parser._parse('01-02-30', :date)
|
225
|
-
time_array.should == [1930,2,1,nil,nil,nil,nil]
|
250
|
+
time_array.should == [1930,2,1,nil,nil,nil,nil,nil]
|
226
251
|
end
|
227
252
|
|
228
253
|
it "should allow custom threshold" do
|
229
254
|
default = Timeliness.ambiguous_year_threshold
|
230
255
|
Timeliness.ambiguous_year_threshold = 40
|
231
256
|
time_array = parser._parse('01-02-39', :date)
|
232
|
-
time_array.should == [2039,2,1,nil,nil,nil,nil]
|
257
|
+
time_array.should == [2039,2,1,nil,nil,nil,nil,nil]
|
233
258
|
time_array = parser._parse('01-02-40', :date)
|
234
|
-
time_array.should == [1940,2,1,nil,nil,nil,nil]
|
259
|
+
time_array.should == [1940,2,1,nil,nil,nil,nil,nil]
|
235
260
|
Timeliness.ambiguous_year_threshold = default
|
236
261
|
end
|
237
262
|
end
|
data/timeliness.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{timeliness}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Adam Meehan"]
|
9
|
-
s.date = %q{2010-10-
|
9
|
+
s.date = %q{2010-10-27}
|
10
10
|
s.description = %q{Fast date/time parser with customisable formats and I18n support.}
|
11
11
|
s.email = %q{adam.meehan@gmail.com}
|
12
12
|
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc"]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timeliness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Meehan
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
18
|
+
date: 2010-10-27 00:00:00 +11:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|