timeliness 0.1.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 +0 -0
- data/LICENSE +20 -0
- data/README.rdoc +242 -0
- data/Rakefile +64 -0
- data/lib/timeliness.rb +35 -0
- data/lib/timeliness/format_set.rb +95 -0
- data/lib/timeliness/formats.rb +221 -0
- data/lib/timeliness/helpers.rb +49 -0
- data/lib/timeliness/parser.rb +94 -0
- data/lib/timeliness/version.rb +3 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/timeliness/format_set_spec.rb +106 -0
- data/spec/timeliness/formats_spec.rb +93 -0
- data/spec/timeliness/parser_spec.rb +354 -0
- data/timeliness.gemspec +29 -0
- metadata +82 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Timeliness::Formats do
|
4
|
+
|
5
|
+
context "add_formats" do
|
6
|
+
before do
|
7
|
+
@default_formats = formats.time_formats.dup
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should add format to format array" do
|
11
|
+
formats.add_formats(:time, "h o'clock")
|
12
|
+
formats.time_formats.should include("h o'clock")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should parse new format after its added" do
|
16
|
+
should_not_parse("12 o'clock", :time)
|
17
|
+
formats.add_formats(:time, "h o'clock")
|
18
|
+
should_parse("12 o'clock", :time)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should raise error if format exists" do
|
22
|
+
lambda { formats.add_formats(:time, "hh:nn:ss") }.should raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with :before option" do
|
26
|
+
it "should add new format with higher precedence" do
|
27
|
+
formats.add_formats(:time, "ss:hh:nn", :before => 'hh:nn:ss')
|
28
|
+
time_array = parser._parse('59:23:58', :time)
|
29
|
+
time_array.should == [nil,nil,nil,23,58,59,nil]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should raise error if :before format does not exist" do
|
33
|
+
lambda { formats.add_formats(:time, "ss:hh:nn", :before => 'nn:hh:ss') }.should raise_error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
formats.time_formats = @default_formats
|
39
|
+
formats.compile_formats
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "remove_formats" do
|
44
|
+
before do
|
45
|
+
@default_formats = formats.time_formats.dup
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should remove format from format array" do
|
49
|
+
formats.remove_formats(:time, 'h.nn_ampm')
|
50
|
+
formats.time_formats.should_not include("h o'clock")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should remove multiple formats from format array" do
|
54
|
+
formats.remove_formats(:time, 'h.nn_ampm')
|
55
|
+
formats.time_formats.should_not include("h o'clock")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should not allow format to be parsed" do
|
59
|
+
should_parse('2.12am', :time)
|
60
|
+
formats.remove_formats(:time, 'h.nn_ampm')
|
61
|
+
should_not_parse('2.12am', :time)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should raise error if format does not exist" do
|
65
|
+
lambda { formats.remove_formats(:time, "ss:hh:nn") }.should raise_error()
|
66
|
+
end
|
67
|
+
|
68
|
+
after do
|
69
|
+
formats.time_formats = @default_formats
|
70
|
+
formats.compile_formats
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "use_euro_formats" do
|
75
|
+
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
|
+
formats.use_euro_formats
|
78
|
+
parser._parse('01/02/2000', :date).should == [2000,2,1,nil,nil,nil,nil]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "use_use_formats" do
|
83
|
+
before do
|
84
|
+
formats.use_euro_formats
|
85
|
+
end
|
86
|
+
|
87
|
+
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
|
+
formats.use_us_formats
|
90
|
+
parser._parse('01/02/2000', :date).should == [2000,1,2,nil,nil,nil,nil]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,354 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Timeliness::Parser do
|
4
|
+
context "parse" do
|
5
|
+
it "should return time object for valid time string" do
|
6
|
+
parse("2000-01-01 12:13:14", :datetime).should be_kind_of(Time)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return nil for datetime string with invalid date part" do
|
10
|
+
should_not_parse("2000-02-30 12:13:14", :datetime)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return nil for datetime string with invalid time part" do
|
14
|
+
should_not_parse("2000-02-01 25:13:14", :datetime)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return nil for invalid date string" do
|
18
|
+
should_not_parse("2000-02-30", :date)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return nil for invalid time string" do
|
22
|
+
should_not_parse("25:00:00", :time)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should ignore time in datetime string for date type" do
|
26
|
+
parse('2000-02-01 12:13', :date).should == Time.local(2000,2,1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should ignore date in datetime string for time type" do
|
30
|
+
parse('2010-02-01 12:13', :time).should == Time.local(2000,1,1,12,13)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return return same value if value not a string" do
|
34
|
+
value = Time.now
|
35
|
+
parse(value, :datetime).should == value
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with :now option" do
|
39
|
+
it 'should use date parts if string does not specify' do
|
40
|
+
time = parse("12:13:14", :now => Time.local(2010,1,1))
|
41
|
+
time.should == Time.local(2010,1,1,12,13,14)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with :zone option" do
|
46
|
+
context ":utc" do
|
47
|
+
it "should return time object in utc timezone" do
|
48
|
+
time = parse("2000-06-01 12:13:14", :datetime, :zone => :utc)
|
49
|
+
time.utc_offset.should == 0
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context ":local" do
|
54
|
+
it "should return time object in local system timezone" do
|
55
|
+
time = parse("2000-06-01 12:13:14", :datetime, :zone => :local)
|
56
|
+
time.utc_offset.should == 10.hours
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context ":current" do
|
61
|
+
it "should return time object in current timezone" do
|
62
|
+
Time.zone = 'Adelaide'
|
63
|
+
time = parse("2000-06-01 12:13:14", :datetime, :zone => :current)
|
64
|
+
time.utc_offset.should == 9.5.hours
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "named zone" do
|
69
|
+
it "should return time object in the timezone" do
|
70
|
+
time = parse("2000-06-01 12:13:14", :datetime, :zone => 'London')
|
71
|
+
time.utc_offset.should == 1.hour
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "for time type" do
|
77
|
+
it 'should use date from date_for_time_type' do
|
78
|
+
parse('12:13:14', :time).should == Time.local(2000,1,1,12,13,14)
|
79
|
+
end
|
80
|
+
|
81
|
+
context "with :now option" do
|
82
|
+
it 'should use date from :now' do
|
83
|
+
parse('12:13:14', :time, :now => Time.local(2010, 6, 1)).should == Time.local(2010,6,1,12,13,14)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "with :zone option" do
|
88
|
+
before(:all) do
|
89
|
+
Timecop.freeze(2010,1,1,0,0,0)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should use date from the specified zone" do
|
93
|
+
time = parse("12:13:14", :time, :zone => :utc)
|
94
|
+
time.year.should == 2009
|
95
|
+
time.month.should == 12
|
96
|
+
time.day.should == 31
|
97
|
+
end
|
98
|
+
|
99
|
+
after(:all) do
|
100
|
+
Timecop.return
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "_parse" do
|
107
|
+
context "with type" do
|
108
|
+
it "should return date array from date string" do
|
109
|
+
time_array = parser._parse('2000-02-01', :date)
|
110
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should return time array from time string" do
|
114
|
+
time_array = parser._parse('12:13:14', :time)
|
115
|
+
time_array.should == [nil,nil,nil,12,13,14,nil]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return datetime array from datetime string" do
|
119
|
+
time_array = parser._parse('2000-02-01 12:13:14', :datetime)
|
120
|
+
time_array.should == [2000,2,1,12,13,14,nil]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should return date array from date string when type is datetime" do
|
124
|
+
time_array = parser._parse('2000-02-01', :datetime)
|
125
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return datetime array from datetime string when type is date" do
|
129
|
+
time_array = parser._parse('2000-02-01 12:13:14', :date)
|
130
|
+
time_array.should == [2000,2,1,12,13,14,nil]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "with no type" do
|
135
|
+
it "should return date array from date string" do
|
136
|
+
time_array = parser._parse('2000-02-01')
|
137
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return time array from time string" do
|
141
|
+
time_array = parser._parse('12:13:14', :time)
|
142
|
+
time_array.should == [nil,nil,nil,12,13,14,nil]
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should return datetime array from datetime string" do
|
146
|
+
time_array = parser._parse('2000-02-01 12:13:14')
|
147
|
+
time_array.should == [2000,2,1,12,13,14,nil]
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should return date array from date string when type is datetime" do
|
151
|
+
time_array = parser._parse('2000-02-01')
|
152
|
+
time_array.should == [2000,2,1,nil,nil,nil,nil]
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should return datetime array from datetime string when type is date" do
|
156
|
+
time_array = parser._parse('2000-02-01 12:13:14')
|
157
|
+
time_array.should == [2000,2,1,12,13,14,nil]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "with :strict => true" do
|
162
|
+
it "should return nil from date string when type is datetime" do
|
163
|
+
time_array = parser._parse('2000-02-01', :datetime, :strict => true)
|
164
|
+
time_array.should be_nil
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should return nil from datetime string when type is date" do
|
168
|
+
time_array = parser._parse('2000-02-01 12:13:14', :date, :strict => true)
|
169
|
+
time_array.should be_nil
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should return nil from datetime string when type is time" do
|
173
|
+
time_array = parser._parse('2000-02-01 12:13:14', :time, :strict => true)
|
174
|
+
time_array.should be_nil
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should parse date string when type is date" do
|
178
|
+
time_array = parser._parse('2000-02-01', :date, :strict => true)
|
179
|
+
time_array.should_not be_nil
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should parse time string when type is time" do
|
183
|
+
time_array = parser._parse('12:13:14', :time, :strict => true)
|
184
|
+
time_array.should_not be_nil
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should parse datetime string when type is datetime" do
|
188
|
+
time_array = parser._parse('2000-02-01 12:13:14', :datetime, :strict => true)
|
189
|
+
time_array.should_not be_nil
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should ignore strict parsing if no type specified" do
|
193
|
+
time_array = parser._parse('2000-02-01', :strict => true)
|
194
|
+
time_array.should_not be_nil
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should return nil if time hour is out of range for AM meridian" do
|
199
|
+
time_array = parser._parse('13:14 am', :time)
|
200
|
+
time_array.should == nil
|
201
|
+
time_array = parser._parse('00:14 am', :time)
|
202
|
+
time_array.should == nil
|
203
|
+
end
|
204
|
+
|
205
|
+
context "with :format option" do
|
206
|
+
it "should return values if string matches specified format" do
|
207
|
+
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]
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should return nil if string does not match specified format" do
|
212
|
+
time_array = parser._parse('2000-02-01 12:13', :datetime, :format => 'yyyy-mm-dd hh:nn:ss')
|
213
|
+
time_array.should be_nil
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "date with ambiguous year" do
|
218
|
+
it "should return year in current century if year below threshold" do
|
219
|
+
time_array = parser._parse('01-02-29', :date)
|
220
|
+
time_array.should == [2029,2,1,nil,nil,nil,nil]
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should return year in last century if year at or above threshold" do
|
224
|
+
time_array = parser._parse('01-02-30', :date)
|
225
|
+
time_array.should == [1930,2,1,nil,nil,nil,nil]
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should allow custom threshold" do
|
229
|
+
default = Timeliness.ambiguous_year_threshold
|
230
|
+
Timeliness.ambiguous_year_threshold = 40
|
231
|
+
time_array = parser._parse('01-02-39', :date)
|
232
|
+
time_array.should == [2039,2,1,nil,nil,nil,nil]
|
233
|
+
time_array = parser._parse('01-02-40', :date)
|
234
|
+
time_array.should == [1940,2,1,nil,nil,nil,nil]
|
235
|
+
Timeliness.ambiguous_year_threshold = default
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "make_time" do
|
241
|
+
it "should return time object for valid time array" do
|
242
|
+
time = parser.make_time([2010,9,8,12,13,14])
|
243
|
+
time.should == Time.local(2010,9,8,12,13,14)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should return nil for invalid date in array" do
|
247
|
+
time = parser.make_time([2010,13,8,12,13,14])
|
248
|
+
time.should be_nil
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should return nil for invalid time in array" do
|
252
|
+
time = parser.make_time([2010,9,8,25,13,14])
|
253
|
+
time.should be_nil
|
254
|
+
end
|
255
|
+
|
256
|
+
context "default timezone" do
|
257
|
+
before do
|
258
|
+
@default_timezone = Timeliness.default_timezone
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should be used if no zone value" do
|
262
|
+
Timeliness.default_timezone = :utc
|
263
|
+
time = parser.make_time([2000,6,1,12,0,0])
|
264
|
+
time.utc_offset.should == 0
|
265
|
+
end
|
266
|
+
|
267
|
+
after do
|
268
|
+
Timeliness.default_timezone = @default_timezone
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context "with zone value" do
|
273
|
+
context ":utc" do
|
274
|
+
it "should return time object in utc timezone" do
|
275
|
+
time = parser.make_time([2000,6,1,12,0,0], :utc)
|
276
|
+
time.utc_offset.should == 0
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
context ":local" do
|
281
|
+
it "should return time object in local system timezone" do
|
282
|
+
time = parser.make_time([2000,6,1,12,0,0], :local)
|
283
|
+
time.utc_offset.should == 10.hours
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
context ":current" do
|
288
|
+
it "should return time object in current timezone" do
|
289
|
+
Time.zone = 'Adelaide'
|
290
|
+
time = parser.make_time([2000,6,1,12,0,0], :current)
|
291
|
+
time.utc_offset.should == 9.5.hours
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
context "named zone" do
|
296
|
+
it "should return time object in the timezone" do
|
297
|
+
time = parser.make_time([2000,6,1,12,0,0], 'London')
|
298
|
+
time.utc_offset.should == 1.hour
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe "current_date" do
|
305
|
+
before(:all) do
|
306
|
+
Timecop.freeze(2010,1,1,0,0,0)
|
307
|
+
end
|
308
|
+
|
309
|
+
context "with no options" do
|
310
|
+
it 'should return date_for_time_type values with no options' do
|
311
|
+
current_date.should == Timeliness.date_for_time_type
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context "with :now option" do
|
316
|
+
it 'should return date array from Time value' do
|
317
|
+
time = Time.now
|
318
|
+
date_array = [time.year, time.month, time.day]
|
319
|
+
current_date(:now => time).should == date_array
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context "with :zone option" do
|
324
|
+
it 'should return date array for utc zone' do
|
325
|
+
time = Time.now.getutc
|
326
|
+
date_array = [time.year, time.month, time.day]
|
327
|
+
current_date(:zone => :utc).should == date_array
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'should return date array for local zone' do
|
331
|
+
time = Time.now
|
332
|
+
date_array = [time.year, time.month, time.day]
|
333
|
+
current_date(:zone => :local).should == date_array
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'should return date array for current zone' do
|
337
|
+
Time.zone = 'London'
|
338
|
+
time = Time.current
|
339
|
+
date_array = [time.year, time.month, time.day]
|
340
|
+
current_date(:zone => :current).should == date_array
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'should return date array for named zone' do
|
344
|
+
time = Time.use_zone('London') { Time.current }
|
345
|
+
date_array = [time.year, time.month, time.day]
|
346
|
+
current_date(:zone => 'London').should == date_array
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
after(:all) do
|
351
|
+
Timecop.return
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
data/timeliness.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{timeliness}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Adam Meehan"]
|
9
|
+
s.date = %q{2010-10-14}
|
10
|
+
s.description = %q{Fast date/time parser with customisable formats and I18n support.}
|
11
|
+
s.email = %q{adam.meehan@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc"]
|
13
|
+
s.files = ["timeliness.gemspec", "LICENSE", "CHANGELOG.rdoc", "README.rdoc", "Rakefile", "lib/timeliness", "lib/timeliness/format_set.rb", "lib/timeliness/formats.rb", "lib/timeliness/helpers.rb", "lib/timeliness/parser.rb", "lib/timeliness/version.rb", "lib/timeliness.rb", "spec/spec_helper.rb", "spec/timeliness", "spec/timeliness/format_set_spec.rb", "spec/timeliness/formats_spec.rb", "spec/timeliness/parser_spec.rb"]
|
14
|
+
s.homepage = %q{http://github.com/adzap/timeliness}
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.rubyforge_project = %q{timeliness}
|
17
|
+
s.rubygems_version = %q{1.3.7}
|
18
|
+
s.summary = %q{Control time (parsing), quickly.}
|
19
|
+
|
20
|
+
if s.respond_to? :specification_version then
|
21
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
22
|
+
s.specification_version = 3
|
23
|
+
|
24
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
+
else
|
26
|
+
end
|
27
|
+
else
|
28
|
+
end
|
29
|
+
end
|