kronos 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -55,20 +55,59 @@ In contrast, other date parsing libraries, such as [Chronic](http://github.com/m
55
55
 
56
56
  Kronos is currently implemented as a thin wrapper over [ParseDate](http://ruby-doc.org/stdlib/libdoc/parsedate/rdoc/index.html).
57
57
 
58
- ## Future Plans
58
+ ## Date Comparisons
59
59
 
60
- In the future, I would like Kronos to be able to handle date-related comparisons properly.
60
+ Kronos handles date-related comparisons more intelligently.
61
61
 
62
- The Ruby date libraries that I have seen make the assumption that you are specifying a point (i.e. a particular date), not an interval (such as an entire month or year). Comparing intervals adds a little bit of complexity. For example:
62
+ Many Ruby date libraries make the assumption that you are specifying a point (i.e. a particular date), not an interval (such as an entire month or year). Kronos, on the other hand, lets you specify dates that are intervals:
63
63
 
64
- year = Kronos.parse("1974")
65
- month = Kronos.parse("March 1974")
66
- year < month # => false
67
- year > month # => false
68
- month == year # => false
69
- year.in?(month) # => false
70
- month.in?(year) # => true
64
+ k_1973 = Kronos.parse("1973")
65
+ k_1974 = Kronos.parse("1974")
66
+ k_march_1974 = Kronos.parse("March 1974")
67
+
68
+ With Kronos, you can compare date objects as follows:
69
+
70
+ k_1973 < k_1973 # => true
71
+ k_1973 < k_march_1974 # => true
72
+
73
+ ### A Note about Kronos Comparison Operators
74
+
75
+ Kronos interprets "<" as "Does the date interval on the left occur completely before the date interval on the right?" In other words, if there is overlap, the result will be false.
76
+
77
+ Here's an example. If you ask "Does the year 1974 came before March 1974?" a careful response might be: "Actually, part of it comes before and part of it comes after. Your question does not really make sense because March 1974 is contained within the year 1974."
78
+
79
+ Because of this, Konos comparison operators (<, ==, >) behave a little bit differently for Kronos objects than for, say, integers. Given any two integers m and n, you can be sure that one of the operators holds. For example:
80
+
81
+ m = 1
82
+ n = 2
83
+ m < n # => true
84
+ m == n # => false
85
+ m > n # => false
86
+
87
+ However, given two Kronos objects k1 and k2 you cannot guarantee that one of the operators will hold. For example:
88
+
89
+ k_1974 < k_march_1974 # => false
90
+ k_1973 == k_march_1974 # => false
91
+ k_1974 > k_march_1974 # => false
92
+
93
+ Since the two dates are unequal but overlap, Kronos will always return false.
94
+
95
+ ### Future Work
96
+
97
+ I plan to implement the `in?` method as follows:
98
+
99
+ k_march_1974.in?(k_1974) # => true
100
+ k_1974.in?(k_march_1974) # => false
101
+
102
+ ## History
103
+
104
+ We import a lot of data from government Web sites as part of our work at the Sunlight Labs (the technical arm of the Sunlight Foundation). I did not want to store date-related information in a way that made it seem more precise than it really was, so I wrote this little library. -David
105
+
106
+ ## Contributors
107
+
108
+ David James (djsun)
109
+ Eric Mill (klondike)
71
110
 
72
111
  ## Feedback
73
112
 
74
- I would appreciate your feedback. Thanks! (David James, Sunlight Labs, Washington, DC)
113
+ We would appreciate your feedback. Thanks!
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{kronos}
8
- s.version = "0.1.3"
8
+ s.version = "0.1.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David James"]
12
- s.date = %q{2009-12-11}
12
+ s.date = %q{2010-03-09}
13
13
  s.description = %q{Kronos provides flexible date parsing. Currently just a thin layer on top of ParseDate.}
14
14
  s.email = %q{djames@sunlightfoundation.com}
15
15
  s.extra_rdoc_files = [
@@ -25,18 +25,22 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "kronos.gemspec",
27
27
  "lib/kronos.rb",
28
+ "spec/compare_spec.rb",
28
29
  "spec/kronos_spec.rb",
29
30
  "spec/spec.opts",
30
- "spec/spec_helper.rb"
31
+ "spec/spec_helper.rb",
32
+ "spec/valid_spec.rb"
31
33
  ]
32
34
  s.homepage = %q{http://github.com/djsun/kronos}
33
35
  s.rdoc_options = ["--charset=UTF-8"]
34
36
  s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.5}
37
+ s.rubygems_version = %q{1.3.6}
36
38
  s.summary = %q{Simple and flexible date parsing.}
37
39
  s.test_files = [
38
- "spec/kronos_spec.rb",
39
- "spec/spec_helper.rb"
40
+ "spec/compare_spec.rb",
41
+ "spec/kronos_spec.rb",
42
+ "spec/spec_helper.rb",
43
+ "spec/valid_spec.rb"
40
44
  ]
41
45
 
42
46
  if s.respond_to? :specification_version then
@@ -29,6 +29,94 @@ class Kronos
29
29
  self
30
30
  end
31
31
 
32
+ def valid?
33
+ if day
34
+ return false unless month && year
35
+ end
36
+ if month
37
+ return false unless year
38
+ end
39
+ true
40
+ end
41
+
42
+ def <(other)
43
+ if !self.year || !other.year
44
+ false
45
+ elsif self.year < other.year
46
+ true
47
+ elsif self.year > other.year
48
+ false
49
+ elsif self.year == other.year
50
+ if !self.month || !other.month
51
+ false
52
+ elsif self.month < other.month
53
+ true
54
+ elsif self.month > other.month
55
+ false
56
+ elsif self.month == other.month
57
+ if !self.day || !other.day
58
+ false
59
+ elsif self.day < other.day
60
+ true
61
+ elsif self.day > other.day
62
+ false
63
+ elsif self.day == other.day
64
+ false
65
+ else
66
+ raise "Unexpected"
67
+ end
68
+ end
69
+ else
70
+ raise "Unexpected"
71
+ end
72
+ end
73
+
74
+ def <=(other)
75
+ (self < other) || (self == other)
76
+ end
77
+
78
+ def ==(other)
79
+ self.year == other.year &&
80
+ self.month == other.month &&
81
+ self.day == other.day
82
+ end
83
+
84
+ def >=(other)
85
+ (self > other) || (self == other)
86
+ end
87
+
88
+ def >(other)
89
+ if !self.year || !other.year
90
+ false
91
+ elsif self.year < other.year
92
+ false
93
+ elsif self.year > other.year
94
+ true
95
+ elsif self.year == other.year
96
+ if !self.month || !other.month
97
+ false
98
+ elsif self.month < other.month
99
+ false
100
+ elsif self.month > other.month
101
+ true
102
+ elsif self.month == other.month
103
+ if !self.day || !other.day
104
+ false
105
+ elsif self.day < other.day
106
+ false
107
+ elsif self.day > other.day
108
+ true
109
+ elsif self.day == other.day
110
+ false
111
+ else
112
+ raise "Unexpected"
113
+ end
114
+ end
115
+ else
116
+ raise "Unexpected"
117
+ end
118
+ end
119
+
32
120
  def to_hash
33
121
  h = {}
34
122
  h['year'] = year if year
@@ -0,0 +1,229 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Kronos Comparisons" do
4
+
5
+ def new_kronos(year=nil, month=nil, day=nil)
6
+ k = Kronos.new
7
+ k.year = year if year
8
+ k.month = month if month
9
+ k.day = day if day
10
+ k
11
+ end
12
+
13
+ describe "2005 vs 2005" do
14
+ before do
15
+ @k1 = new_kronos(2005)
16
+ @k2 = new_kronos(2005)
17
+ end
18
+
19
+ it "should not be <" do
20
+ (@k1 < @k2).should == false
21
+ end
22
+
23
+ it "should be <=" do
24
+ (@k1 <= @k2).should == true
25
+ end
26
+
27
+ it "should be ==" do
28
+ (@k1 == @k2).should == true
29
+ end
30
+
31
+ it "should be >=" do
32
+ (@k1 >= @k2).should == true
33
+ end
34
+
35
+ it "should not be >" do
36
+ (@k1 > @k2).should == false
37
+ end
38
+
39
+ end
40
+
41
+ describe "2005 vs 2006" do
42
+ before do
43
+ @k1 = new_kronos(2005)
44
+ @k2 = new_kronos(2006)
45
+ end
46
+
47
+ it "should be <" do
48
+ (@k1 < @k2).should == true
49
+ end
50
+
51
+ it "should be <=" do
52
+ (@k1 <= @k2).should == true
53
+ end
54
+
55
+ it "should not be ==" do
56
+ (@k1 == @k2).should == false
57
+ end
58
+
59
+ it "should not be >" do
60
+ (@k1 > @k2).should == false
61
+ end
62
+
63
+ it "should not be >=" do
64
+ (@k1 >= @k2).should == false
65
+ end
66
+ end
67
+
68
+ describe "March 2005 vs 2006" do
69
+ before do
70
+ @k1 = new_kronos(2005, 3)
71
+ @k2 = new_kronos(2006)
72
+ end
73
+
74
+ it "should be <" do
75
+ (@k1 < @k2).should == true
76
+ end
77
+
78
+ it "should be <=" do
79
+ (@k1 <= @k2).should == true
80
+ end
81
+
82
+ it "should not be ==" do
83
+ (@k1 == @k2).should == false
84
+ end
85
+
86
+ it "should not be >" do
87
+ (@k1 > @k2).should == false
88
+ end
89
+
90
+ it "should not be >=" do
91
+ (@k1 >= @k2).should == false
92
+ end
93
+ end
94
+
95
+ describe "April 2000 vs May 2000" do
96
+ before do
97
+ @k1 = new_kronos(2000, 4)
98
+ @k2 = new_kronos(2000, 5)
99
+ end
100
+
101
+ it "should be <" do
102
+ (@k1 < @k2).should == true
103
+ end
104
+
105
+ it "should be <=" do
106
+ (@k1 <= @k2).should == true
107
+ end
108
+
109
+ it "should not be ==" do
110
+ (@k1 == @k2).should == false
111
+ end
112
+
113
+ it "should not be >" do
114
+ (@k1 > @k2).should == false
115
+ end
116
+
117
+ it "should not be >=" do
118
+ (@k1 >= @k2).should == false
119
+ end
120
+ end
121
+
122
+ describe "April 10, 2000 vs May 1, 2000" do
123
+ before do
124
+ @k1 = new_kronos(2000, 4, 10)
125
+ @k2 = new_kronos(2000, 5, 1)
126
+ end
127
+
128
+ it "should be <" do
129
+ (@k1 < @k2).should == true
130
+ end
131
+
132
+ it "should be <=" do
133
+ (@k1 <= @k2).should == true
134
+ end
135
+
136
+ it "should not be ==" do
137
+ (@k1 == @k2).should == false
138
+ end
139
+
140
+ it "should not be >" do
141
+ (@k1 > @k2).should == false
142
+ end
143
+
144
+ it "should not be >=" do
145
+ (@k1 >= @k2).should == false
146
+ end
147
+ end
148
+
149
+ describe "April 10, 2000 vs May 2000" do
150
+ before do
151
+ @k1 = new_kronos(2000, 4, 10)
152
+ @k2 = new_kronos(2000, 5)
153
+ end
154
+
155
+ it "should be <" do
156
+ (@k1 < @k2).should == true
157
+ end
158
+
159
+ it "should be <=" do
160
+ (@k1 <= @k2).should == true
161
+ end
162
+
163
+ it "should not be ==" do
164
+ (@k1 == @k2).should == false
165
+ end
166
+
167
+ it "should not be >" do
168
+ (@k1 > @k2).should == false
169
+ end
170
+
171
+ it "should not be >=" do
172
+ (@k1 >= @k2).should == false
173
+ end
174
+ end
175
+
176
+ describe "April 10, 2000 vs April 8, 2000" do
177
+ before do
178
+ @k1 = new_kronos(2000, 4, 10)
179
+ @k2 = new_kronos(2000, 4, 8)
180
+ end
181
+
182
+ it "should not be <" do
183
+ (@k1 < @k2).should == false
184
+ end
185
+
186
+ it "should not be <=" do
187
+ (@k1 <= @k2).should == false
188
+ end
189
+
190
+ it "should not be ==" do
191
+ (@k1 == @k2).should == false
192
+ end
193
+
194
+ it "should be >" do
195
+ (@k1 > @k2).should == true
196
+ end
197
+
198
+ it "should be >=" do
199
+ (@k1 >= @k2).should == true
200
+ end
201
+ end
202
+
203
+ describe "(blank) vs 2000" do
204
+ before do
205
+ @k1 = new_kronos()
206
+ @k2 = new_kronos(2000)
207
+ end
208
+
209
+ it "should not be <" do
210
+ (@k1 < @k2).should == false
211
+ end
212
+
213
+ it "should not be <=" do
214
+ (@k1 <= @k2).should == false
215
+ end
216
+
217
+ it "should not be ==" do
218
+ (@k1 == @k2).should == false
219
+ end
220
+
221
+ it "should not be >" do
222
+ (@k1 > @k2).should == false
223
+ end
224
+
225
+ it "should not be >=" do
226
+ (@k1 >= @k2).should == false
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Kronos Comparisons" do
4
+
5
+ def new_kronos(year=nil, month=nil, day=nil)
6
+ k = Kronos.new
7
+ k.year = year if year
8
+ k.month = month if month
9
+ k.day = day if day
10
+ k
11
+ end
12
+
13
+ it "year only is valid" do
14
+ new_kronos(2005).valid?.should == true
15
+ end
16
+
17
+ it "month and year is valid" do
18
+ new_kronos(2005, 8).valid?.should == true
19
+ end
20
+
21
+ it "month, day, and year is valid" do
22
+ new_kronos(2005, 8, 22).valid?.should == true
23
+ end
24
+
25
+ it "day and year is invalid" do
26
+ new_kronos(2005, nil, 22).valid?.should == false
27
+ end
28
+
29
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kronos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 4
9
+ version: 0.1.4
5
10
  platform: ruby
6
11
  authors:
7
12
  - David James
@@ -9,19 +14,23 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-12-11 00:00:00 -05:00
17
+ date: 2010-03-09 00:00:00 -05:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: rspec
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
23
31
  version: 1.2.9
24
- version:
32
+ type: :development
33
+ version_requirements: *id001
25
34
  description: Kronos provides flexible date parsing. Currently just a thin layer on top of ParseDate.
26
35
  email: djames@sunlightfoundation.com
27
36
  executables: []
@@ -40,9 +49,11 @@ files:
40
49
  - VERSION
41
50
  - kronos.gemspec
42
51
  - lib/kronos.rb
52
+ - spec/compare_spec.rb
43
53
  - spec/kronos_spec.rb
44
54
  - spec/spec.opts
45
55
  - spec/spec_helper.rb
56
+ - spec/valid_spec.rb
46
57
  has_rdoc: true
47
58
  homepage: http://github.com/djsun/kronos
48
59
  licenses: []
@@ -56,21 +67,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
67
  requirements:
57
68
  - - ">="
58
69
  - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
59
72
  version: "0"
60
- version:
61
73
  required_rubygems_version: !ruby/object:Gem::Requirement
62
74
  requirements:
63
75
  - - ">="
64
76
  - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
65
79
  version: "0"
66
- version:
67
80
  requirements: []
68
81
 
69
82
  rubyforge_project:
70
- rubygems_version: 1.3.5
83
+ rubygems_version: 1.3.6
71
84
  signing_key:
72
85
  specification_version: 3
73
86
  summary: Simple and flexible date parsing.
74
87
  test_files:
88
+ - spec/compare_spec.rb
75
89
  - spec/kronos_spec.rb
76
90
  - spec/spec_helper.rb
91
+ - spec/valid_spec.rb