timeliness 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,7 @@
1
+ = 0.3.3 - 2011-01-02
2
+ * Add String core extension for to_time, to_date and to_datetime methods, like ActiveSupport
3
+ * Allow arbitrary format string as :format option and it will be compiled, if not found.
4
+
1
5
  = 0.3.2 - 2010-11-26
2
6
  * Catch all errors for ActiveSupport not being loaded for more helpful error
3
7
 
data/README.rdoc CHANGED
@@ -130,6 +130,17 @@ The last two value are the microseconds, and zone abbreviation or offset.
130
130
  Note: The format for this value is not defined. You can add it yourself, easily.
131
131
 
132
132
 
133
+ === ActiveSupport Core Extensions
134
+
135
+ To make it easier to use the parser in Rails or an app using ActiveSupport, you can add/override the methods
136
+ for <tt>to_time</tt>, <tt>to_date</tt> and <tt>to_datetime</tt> on a string value. These methods will then use
137
+ the Timeliness parser for converting a string, instead of the default.
138
+
139
+ You just need to add this line to an initializer or other application file:
140
+
141
+ require 'timeliness/core_ext'
142
+
143
+
133
144
  == Formats
134
145
 
135
146
  The gem has default formats included which can be easily added to using the format syntax. Also
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'rubygems'
2
2
  require 'rake/rdoctask'
3
- require 'rubygems/specification'
4
3
  require 'rspec/core/rake_task'
5
4
 
6
5
  GEM_NAME = "timeliness"
data/benchmark.rb CHANGED
@@ -2,18 +2,18 @@ $:.unshift(File.expand_path('lib'))
2
2
 
3
3
  require 'benchmark'
4
4
  require 'time'
5
- require 'parsedate'
5
+ require 'parsedate' unless RUBY_VERSION =~ /^1\.9\./
6
6
  require 'timeliness'
7
7
 
8
8
  if defined?(JRUBY_VERSION)
9
9
  # Warm up JRuby
10
- 20000.times do
10
+ 20_000.times do
11
11
  Time.parse("2000-01-04 12:12:12")
12
12
  Timeliness::Parser.parse("2000-01-04 12:12:12", :datetime)
13
13
  end
14
14
  end
15
15
 
16
- n = 10000
16
+ n = 10_000
17
17
  Benchmark.bm do |x|
18
18
  x.report('timeliness - datetime') {
19
19
  n.times do
@@ -102,8 +102,7 @@ Benchmark.bm do |x|
102
102
  x.report('ISO regexp for datetime') {
103
103
  n.times do
104
104
  "2000-01-04 12:12:12" =~ /\A(\d{4})-(\d{2})-(\d{2}) (\d{2})[\. :](\d{2})([\. :](\d{2}))?\Z/
105
- microsec = ($7.to_f * 1_000_000).to_i
106
- Time.mktime($1.to_i, $2.to_i, $3.to_i, $3.to_i, $5.to_i, $6.to_i, microsec)
105
+ Time.mktime($1.to_i, $2.to_i, $3.to_i, $3.to_i, $5.to_i, $6.to_i)
107
106
  end
108
107
  }
109
108
 
@@ -133,19 +132,21 @@ Benchmark.bm do |x|
133
132
  end
134
133
  }
135
134
 
136
- x.report('parsedate - valid') {
137
- n.times do
138
- arr = ParseDate.parsedate("2000-01-04 12:12:12")
139
- Date.new(*arr[0..2])
140
- Time.mktime(*arr)
141
- end
142
- }
135
+ if defined?(ParseDate)
136
+ x.report('parsedate - valid') {
137
+ n.times do
138
+ arr = ParseDate.parsedate("2000-01-04 12:12:12")
139
+ Date.new(*arr[0..2])
140
+ Time.mktime(*arr)
141
+ end
142
+ }
143
143
 
144
- x.report('parsedate - invalid ') {
145
- n.times do
146
- arr = ParseDate.parsedate("2000-00-04 12:12:12")
147
- end
148
- }
144
+ x.report('parsedate - invalid ') {
145
+ n.times do
146
+ arr = ParseDate.parsedate("2000-00-04 12:12:12")
147
+ end
148
+ }
149
+ end
149
150
 
150
151
  x.report('strptime - valid') {
151
152
  n.times do
@@ -0,0 +1,6 @@
1
+ require 'timeliness/core_ext/string'
2
+
3
+ module Timeliness
4
+ module CoreExt
5
+ end
6
+ end
@@ -0,0 +1,22 @@
1
+ class String
2
+
3
+ # Form can be either :utc (default) or :local.
4
+ def to_time(form = :utc)
5
+ return nil if self.blank?
6
+ Timeliness::Parser.parse(self, :datetime, :zone => form)
7
+ end
8
+
9
+ def to_date
10
+ return nil if self.blank?
11
+ values = Timeliness::Parser._parse(self, :date).map { |arg| arg || 0 }
12
+ ::Date.new(*values[0..2])
13
+ end
14
+
15
+ def to_datetime
16
+ return nil if self.blank?
17
+ values = Timeliness::Parser._parse(self, :datetime).map { |arg| arg || 0 }
18
+ values[7] = values[7]/24.hours.to_f if values[7] != 0
19
+ values[5] += Rational(values.delete_at(6), 1000000)
20
+ ::DateTime.civil(*values)
21
+ end
22
+ end
@@ -76,14 +76,16 @@ module Timeliness
76
76
  'ddd, dd mmm yyyy hh:nn:ss zo', # RFC 822
77
77
  'ddd mmm d hh:nn:ss zo yyyy', # Ruby time string
78
78
  'yyyy-mm-ddThh:nn:ssZ', # ISO 8601 without zone offset
79
- 'yyyy-mm-ddThh:nn:sszo' # ISO 8601 with zone offset
79
+ 'yyyy-mm-ddThh:nn:sszo', # ISO 8601 with zone offset
80
+ 'yyyy-mm-ddThh:nn:ss.u', # ISO 8601 with usec
81
+ 'yyyy-mm-ddThh:nn:ss.uzo' # ISO 8601 with usec and offset
80
82
  ]
81
83
 
82
84
  # All tokens available for format construction. The token array is made of
83
85
  # regexp and key for format component mapping, if any.
84
86
  #
85
87
  @format_tokens = {
86
- 'ddd' => [ '\w{3,9}' ],
88
+ 'ddd' => [ '\w{3,9}', :wday ],
87
89
  'dd' => [ '\d{2}', :day ],
88
90
  'd' => [ '\d{1,2}', :day ],
89
91
  'mmm' => [ '\w{3,9}', :month ],
@@ -38,8 +38,8 @@ module Timeliness
38
38
  @regexp_string = format
39
39
  @regexp = Regexp.new("^(#{format})$")
40
40
  self
41
- rescue
42
- raise "The format '#{format_string}' failed to compile using regexp string #{format}."
41
+ rescue => ex
42
+ raise "The format '#{format_string}' failed to compile using regexp string #{format}. Error: #{ex.inspect}"
43
43
  end
44
44
 
45
45
  # Redefined on compile
@@ -28,7 +28,7 @@ module Timeliness
28
28
  end
29
29
 
30
30
  def match(string, format_string=nil)
31
- format = @formats_hash[format_string] if format_string
31
+ format = single_format(format_string) if format_string
32
32
  match_regexp = format && format.regexp || @regexp
33
33
 
34
34
  if match_data = match_regexp.match(string)
@@ -40,5 +40,8 @@ module Timeliness
40
40
  end
41
41
  end
42
42
 
43
+ def single_format(format_string)
44
+ @formats_hash[format_string] || Format.new(format_string).compile!
45
+ end
43
46
  end
44
47
  end
@@ -1,3 +1,3 @@
1
1
  module Timeliness
2
- VERSION = '0.3.2'
2
+ VERSION = '0.3.3'
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ require 'rspec'
3
3
  require 'active_support/time'
4
4
  require 'timecop'
5
5
  require 'timeliness'
6
+ require 'timeliness/core_ext'
6
7
 
7
8
  module TimelinessHelpers
8
9
  def parser
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Timeliness::CoreExt, 'String' do
4
+ # Test values taken from ActiveSupport unit tests for compatibility
5
+
6
+ describe "#to_time" do
7
+ it 'should convert valid string to Time object in default zone' do
8
+ "2005-02-27 23:50".to_time.should == Time.utc(2005, 2, 27, 23, 50)
9
+ end
10
+
11
+ it 'should convert ISO 8601 string to Time object' do
12
+ "2005-02-27T23:50:19.275038".to_time.should == Time.utc(2005, 2, 27, 23, 50, 19, 275038)
13
+ end
14
+
15
+ context "with :local" do
16
+ it 'should convert valid string to local time' do
17
+ "2005-02-27 23:50".to_time(:local).should == Time.local(2005, 2, 27, 23, 50)
18
+ end
19
+
20
+ it 'should convert ISO 8601 string to local time' do
21
+ "2005-02-27T23:50:19.275038".to_time(:local).should == Time.local(2005, 2, 27, 23, 50, 19, 275038)
22
+ end
23
+ end
24
+
25
+ it 'should convert valid future string to Time object' do
26
+ "2039-02-27 23:50".to_time(:local).should == Time.local_time(2039, 2, 27, 23, 50)
27
+ end
28
+
29
+ it 'should convert valid future string to Time object' do
30
+ "2039-02-27 23:50".to_time.should == DateTime.civil(2039, 2, 27, 23, 50)
31
+ end
32
+
33
+ it 'should convert empty string to nil' do
34
+ ''.to_time.should be_nil
35
+ end
36
+ end
37
+
38
+ describe "#to_datetime" do
39
+ it 'should convert valid string to DateTime object' do
40
+ "2039-02-27 23:50".to_datetime.should == DateTime.civil(2039, 2, 27, 23, 50)
41
+ end
42
+
43
+ it 'should convert to DateTime object with UTC offset' do
44
+ "2039-02-27 23:50".to_datetime.offset.should == 0
45
+ end
46
+
47
+ it 'should convert ISO 8601 string to DateTime object' do
48
+ datetime = DateTime.civil(2039, 2, 27, 23, 50, 19 + Rational(275038, 1000000), "-04:00")
49
+ "2039-02-27T23:50:19.275038-04:00".to_datetime.should == datetime
50
+ end
51
+
52
+ it 'should use Rubys default start value' do
53
+ # Taken from ActiveSupport unit tests. Not sure on the implication.
54
+ "2039-02-27 23:50".to_datetime.start.should == ::Date::ITALY
55
+ end
56
+
57
+ it 'should convert empty string to nil' do
58
+ ''.to_datetime.should be_nil
59
+ end
60
+ end
61
+
62
+ describe "#to_date" do
63
+ it 'should convert string to Date object' do
64
+ "2005-02-27".to_date.should == Date.new(2005, 2, 27)
65
+ end
66
+
67
+ it 'should convert empty string to nil' do
68
+ ''.to_date.should be_nil
69
+ end
70
+ end
71
+
72
+ end
@@ -88,6 +88,11 @@ describe Timeliness::FormatSet do
88
88
  set.match('2000-01-02', 'yyyy-mm-dd').should be_kind_of(Array)
89
89
  set.match('2000-01-02', 'dd/mm/yyyy').should be_nil
90
90
  end
91
+
92
+ it 'should compile unknown format for one off match' do
93
+ set.match('20001011').should be_nil
94
+ set.match('20001011', 'yyyymmdd').should be_kind_of(Array)
95
+ end
91
96
  end
92
97
 
93
98
  def compile_regexp(format)
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timeliness
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 3
9
- - 2
10
- version: 0.3.2
8
+ - 3
9
+ version: 0.3.3
11
10
  platform: ruby
12
11
  authors:
13
12
  - Adam Meehan
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-11-28 00:00:00 +11:00
17
+ date: 2011-01-02 00:00:00 +11:00
19
18
  default_executable:
20
19
  dependencies: []
21
20
 
@@ -37,6 +36,8 @@ files:
37
36
  - Rakefile
38
37
  - benchmark.rb
39
38
  - lib/timeliness.rb
39
+ - lib/timeliness/core_ext.rb
40
+ - lib/timeliness/core_ext/string.rb
40
41
  - lib/timeliness/definitions.rb
41
42
  - lib/timeliness/format.rb
42
43
  - lib/timeliness/format_set.rb
@@ -44,6 +45,7 @@ files:
44
45
  - lib/timeliness/parser.rb
45
46
  - lib/timeliness/version.rb
46
47
  - spec/spec_helper.rb
48
+ - spec/timeliness/core_ext/string_spec.rb
47
49
  - spec/timeliness/definitions_spec.rb
48
50
  - spec/timeliness/format_set_spec.rb
49
51
  - spec/timeliness/format_spec.rb
@@ -63,7 +65,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
63
65
  requirements:
64
66
  - - ">="
65
67
  - !ruby/object:Gem::Version
66
- hash: 3
67
68
  segments:
68
69
  - 0
69
70
  version: "0"
@@ -72,7 +73,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
73
  requirements:
73
74
  - - ">="
74
75
  - !ruby/object:Gem::Version
75
- hash: 3
76
76
  segments:
77
77
  - 0
78
78
  version: "0"
@@ -85,6 +85,7 @@ specification_version: 3
85
85
  summary: Date/time parsing for the control freak.
86
86
  test_files:
87
87
  - spec/spec_helper.rb
88
+ - spec/timeliness/core_ext/string_spec.rb
88
89
  - spec/timeliness/definitions_spec.rb
89
90
  - spec/timeliness/format_set_spec.rb
90
91
  - spec/timeliness/format_spec.rb