edtf 2.3.1 → 3.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dcceec6058c69ebeff88be3fdbf269ee69f69fab
4
- data.tar.gz: 4790a440bd05bb6bef2335bbeccc84836051e23c
3
+ metadata.gz: aa655e4e89a8cb161181b107461ecfc658d4c9e9
4
+ data.tar.gz: d463ec75229bb90823ff4972dea2a7cf6fe6e2d4
5
5
  SHA512:
6
- metadata.gz: d08ef863ffaf2ffc248f1213af38b25c6ae1963bbce4599735bedef87d0c025f3d4bc329cb5fc3a89d018c8b3a144693784bbecec163a970909f6e502e1b49cd
7
- data.tar.gz: eee5144c546253056593e414621a4b9202999bf0a7f15fbdd1e0e7fa88835a67f4eb384eaf4eb9f8a287b0964daa465dae352f5d606705febd8d95610c5577ee
6
+ metadata.gz: 673e1462165a23d661c145305041799a1cc1c9dd8ea2129c19a549b5e17eade2271e48fbdc9b6038fbde747d90149e2b5b6f78f01d63c6606efb6b49b44ade61
7
+ data.tar.gz: e36ba83aacd9675b9cc3a59360ddb4428b55629ec28cbaaac48be4f413aa685d9ca984bb878af3d3c365159e9249788660e1c2442571d2bc8448e9d91c5ed3a4
@@ -1,15 +1,17 @@
1
1
  language: ruby
2
2
  bundler_args: --without debug extra
3
+ sudo: false
4
+ cache: bundler
5
+ before_install:
6
+ - gem install bundler
3
7
  script: bundle exec rake test_with_coveralls
4
8
  rvm:
5
- - 2.2
6
- - 2.1
7
- - 2.0
8
- - jruby-19mode
9
- - rbx-2
9
+ - 2.3.1
10
+ - 2.2.5
11
+ - jruby-9.0.5.0
10
12
  notifications:
11
13
  email:
12
14
  - sk@semicolon.at
13
15
  - namyra@gmail.com
14
16
  on_success: change
15
- on_failure: always
17
+ on_failure: change
data/README.md CHANGED
@@ -26,6 +26,11 @@ but we are not testing compatibility actively anymore). Active Support's date
26
26
  extensions are currently listed as a dependency, because of many functional
27
27
  overlaps (version 3.x and 4.x are supported).
28
28
 
29
+ ### ISO 8601-2
30
+
31
+ A variation of EDTF will part of the upcoming ISO 8601-2 standard. EDTF-Ruby
32
+ does not support this new version of EDTF yet, but if you are curious,
33
+ [EDTF.js](inukshuk/edtf.js), an ES6 implementation is already available.
29
34
 
30
35
  Quickstart
31
36
  ----------
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.description = 'A Ruby implementation of the Extended Date/Time Format (EDTF).'
16
16
  s.license = 'BSD-2-Clause-FreeBSD'
17
17
 
18
- s.add_runtime_dependency('activesupport', '>= 3.0', '< 5.0')
18
+ s.add_runtime_dependency('activesupport', '>= 3.0', '< 6.0')
19
19
 
20
20
  s.files = `git ls-files`.split("\n") << 'lib/edtf/parser.rb'
21
21
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,11 +1,11 @@
1
1
  Feature: EDTF parses ISO 8601 interval strings
2
2
  As a user of edtf-ruby
3
3
  I want to parse ISO 8601 interval strings
4
-
4
+
5
5
  Scenario Outline: parse intervals
6
6
  When I parse the string "<string>"
7
7
  Then the interval should cover the date "<date>"
8
-
8
+
9
9
  @004 @level0
10
10
  Scenarios: specification intervals
11
11
  | string | date |
@@ -8,6 +8,12 @@ Feature: Print Date/Time objects as Level 0 EDTF strings
8
8
  When I convert the date
9
9
  Then the EDTF string should be "2004-08-12"
10
10
 
11
+ @001 @level0
12
+ Scenario: Convert simple negative dates
13
+ Given the date "-0300-08-12"
14
+ When I convert the date
15
+ Then the EDTF string should be "-0300-08-12"
16
+
11
17
  @001 @level0
12
18
  Scenario: Convert simple dates with precision
13
19
  Given the date "1980-08-24" with precision set to "day"
@@ -174,7 +174,9 @@ class Date
174
174
  def edtf
175
175
  return "y#{year}" if long_year?
176
176
 
177
- s = FORMATS.take(values.length).zip(values).map { |f,v| f % v }
177
+ v = values
178
+ s = FORMATS.take(v.length).zip(v).map { |f,d| f % d.abs }
179
+ s[0] = "-#{s[0]}" if year < 0
178
180
  s = unspecified.mask(s)
179
181
 
180
182
  unless (h = ua_hash).zero?
@@ -1,5 +1,5 @@
1
1
  module EDTF
2
-
2
+
3
3
  # An interval behaves like a regular Range but is dedicated to EDTF dates.
4
4
  # Most importantly, intervals use the date's precision when generating
5
5
  # the set of contained values and for membership tests. All tests are
@@ -21,20 +21,38 @@ module EDTF
21
21
  class Interval
22
22
 
23
23
  extend Forwardable
24
-
24
+
25
25
  include Comparable
26
26
  include Enumerable
27
27
 
28
28
  # Intervals delegate hash calculation to Ruby Range
29
29
  def_delegators :to_range, :eql?, :hash
30
30
  def_delegators :to_a, :length, :empty?
31
-
32
- attr_accessor :from, :to
31
+
32
+ attr_reader :from, :to
33
33
 
34
34
  def initialize(from = Date.today, to = :open)
35
- @from, @to = from, to
35
+ self.from, self.to = from, to
36
+ end
37
+
38
+ def from=(date)
39
+ case date
40
+ when Date, :unknown
41
+ @from = date
42
+ else
43
+ throw ArgumentError.new("Intervals cannot start with: #{date}")
44
+ end
45
+ end
46
+
47
+ def to=(date)
48
+ case date
49
+ when Date, :unknown, :open
50
+ @to = date
51
+ else
52
+ throw ArgumentError.new("Intervals cannot end with: #{date}")
53
+ end
36
54
  end
37
-
55
+
38
56
  [:open, :unknown].each do |method_name|
39
57
  define_method("#{method_name}_end!") do
40
58
  @to = method_name
@@ -45,34 +63,34 @@ module EDTF
45
63
  @to == method_name
46
64
  end
47
65
  end
48
-
66
+
49
67
  alias open! open_end!
50
68
  alias open? open_end?
51
-
69
+
52
70
  def unknown_start?
53
71
  from == :unknown
54
72
  end
55
-
73
+
56
74
  def unknown_start!
57
75
  @from = :unknown
58
76
  self
59
77
  end
60
-
78
+
61
79
  def unknown?
62
80
  unknown_start? || unknown_end?
63
81
  end
64
-
82
+
65
83
  # Returns the intervals precision. Mixed precisions are currently not
66
84
  # supported; in that case, the start date's precision takes precedence.
67
85
  def precision
68
86
  min.precision || max.precision
69
87
  end
70
-
88
+
71
89
  # Returns true if the precisions of start and end date are not the same.
72
90
  def mixed_precision?
73
91
  min.precision != max.precision
74
92
  end
75
-
93
+
76
94
  def each(&block)
77
95
  step(1, &block)
78
96
  end
@@ -90,37 +108,37 @@ module EDTF
90
108
  # If not block is given, returns an enumerator instead.
91
109
  #
92
110
  def step(by = 1)
93
- raise ArgumentError unless by.respond_to?(:to_i)
94
-
111
+ raise ArgumentError unless by.respond_to?(:to_i)
112
+
95
113
  if block_given?
96
114
  f, t, by = min, max, by.to_i
97
115
 
98
116
  unless f.nil? || t.nil? || by < 1
99
117
  by = { Date::PRECISIONS[precision] => by }
100
-
118
+
101
119
  until f > t do
102
120
  yield f
103
121
  f = f.advance(by)
104
122
  end
105
123
  end
106
-
124
+
107
125
  self
108
126
  else
109
127
  enum_for(:step, by)
110
128
  end
111
129
  end
112
130
 
113
-
131
+
114
132
  # This method always returns false for Range compatibility. EDTF intervals
115
133
  # always include the last date.
116
134
  def exclude_end?
117
135
  false
118
136
  end
119
-
120
-
137
+
138
+
121
139
  # TODO how to handle +/- Infinity for Dates?
122
140
  # TODO we can't delegate to Ruby range for mixed precision intervals
123
-
141
+
124
142
  # Returns the Interval as a Range.
125
143
  def to_range
126
144
  case
@@ -130,7 +148,7 @@ module EDTF
130
148
  Range.new(unknown_start? ? Date.new : @from, max)
131
149
  end
132
150
  end
133
-
151
+
134
152
  # Returns true if other is an element of the Interval, false otherwise.
135
153
  # Comparision is done according to the Interval's min/max date and
136
154
  # precision.
@@ -138,15 +156,15 @@ module EDTF
138
156
  cover?(other) && precision == other.precision
139
157
  end
140
158
  alias member? include?
141
-
159
+
142
160
  # Returns true if other is an element of the Interval, false otherwise.
143
161
  # In contrast to #include? and #member? this method does not take into
144
- # account the date's precision.
162
+ # account the date's precision.
145
163
  def cover?(other)
146
164
  return false unless other.is_a?(Date)
147
-
165
+
148
166
  other = other.day_precision
149
-
167
+
150
168
  case
151
169
  when unknown_start?
152
170
  max.day_precision! == other
@@ -158,7 +176,7 @@ module EDTF
158
176
  min.day_precision! <= other && other <= max.day_precision!
159
177
  end
160
178
  end
161
-
179
+
162
180
  # call-seq:
163
181
  # interval.first -> Date or nil
164
182
  # interval.first(n) -> Array
@@ -166,12 +184,12 @@ module EDTF
166
184
  # Returns the first date in the interval, or the first n dates.
167
185
  def first(n = 1)
168
186
  if n > 1
169
- (ds = Array(min)).empty? ? ds : ds.concat(ds[0].next(n - 1))
187
+ (ds = Array(min)).empty? ? ds : ds.concat(ds[0].next(n - 1))
170
188
  else
171
189
  min
172
190
  end
173
191
  end
174
-
192
+
175
193
  # call-seq:
176
194
  # interval.last -> Date or nil
177
195
  # interval.last(n) -> Array
@@ -179,12 +197,12 @@ module EDTF
179
197
  # Returns the last date in the interval, or the last n dates.
180
198
  def last(n = 1)
181
199
  if n > 1
182
- (ds = Array(max)).empty? ? ds : ds.concat(ds[0].prev(n - 1))
200
+ (ds = Array(max)).empty? ? ds : ds.concat(ds[0].prev(n - 1))
183
201
  else
184
202
  max
185
203
  end
186
204
  end
187
-
205
+
188
206
  # call-seq:
189
207
  # interval.min -> Date or nil
190
208
  # interval.min { |a,b| block } -> Date or nil
@@ -209,11 +227,11 @@ module EDTF
209
227
  end
210
228
  end
211
229
  end
212
-
230
+
213
231
  def begin
214
232
  min
215
233
  end
216
-
234
+
217
235
  # call-seq:
218
236
  # interval.max -> Date or nil
219
237
  # interval.max { |a,b| block } -> Date or nil
@@ -233,7 +251,7 @@ module EDTF
233
251
  case
234
252
  when open_end?, unknown_end?, !unknown_start? && to < from
235
253
  nil
236
- when to.day_precision?
254
+ when to.day_precision?
237
255
  to
238
256
  when to.month_precision?
239
257
  to.end_of_month
@@ -242,11 +260,11 @@ module EDTF
242
260
  end
243
261
  end
244
262
  end
245
-
263
+
246
264
  def end
247
265
  max
248
266
  end
249
-
267
+
250
268
  def <=>(other)
251
269
  case other
252
270
  when Interval, Season, Epoch
@@ -257,7 +275,7 @@ module EDTF
257
275
  nil
258
276
  end
259
277
  end
260
-
278
+
261
279
  def ===(other)
262
280
  case other
263
281
  when Interval
@@ -268,8 +286,8 @@ module EDTF
268
286
  false
269
287
  end
270
288
  end
271
-
272
-
289
+
290
+
273
291
  # Returns the Interval as an EDTF string.
274
292
  def edtf
275
293
  [
@@ -277,9 +295,9 @@ module EDTF
277
295
  to.send(to.respond_to?(:edtf) ? :edtf : :to_s)
278
296
  ] * '/'
279
297
  end
280
-
298
+
281
299
  alias to_s edtf
282
-
300
+
283
301
  end
284
-
302
+
285
303
  end
@@ -1,3 +1,3 @@
1
1
  module EDTF
2
- VERSION = '2.3.1'.freeze
2
+ VERSION = '3.0.0'.freeze
3
3
  end
@@ -5,7 +5,7 @@ describe 'Date/DateTime' do
5
5
  expect(Date).to respond_to(:edtf)
6
6
  end
7
7
  end
8
-
8
+
9
9
  describe 'instance methods' do
10
10
  [:uncertain?, :approximate?, :unspecified?, :uncertain, :approximate, :unspecified].each do |method|
11
11
  it "responds to #{method}" do
@@ -13,14 +13,14 @@ describe 'Date/DateTime' do
13
13
  end
14
14
  end
15
15
  end
16
-
16
+
17
17
  describe '#dup' do
18
18
  let(:date) { Date.edtf('2004-09?~') }
19
-
19
+
20
20
  it 'copies all date values' do
21
21
  date.dup.to_s == '2004-09-01'
22
22
  end
23
-
23
+
24
24
  it 'copies uncertainty' do
25
25
  expect(date.dup).to be_uncertain
26
26
  end
@@ -32,50 +32,50 @@ describe 'Date/DateTime' do
32
32
  it 'copies precision' do
33
33
  expect(date.dup.precision).to eq(:month)
34
34
  end
35
-
35
+
36
36
  it 'copies uncertainty by value' do
37
37
  expect { date.dup.certain! }.not_to change { date.uncertain? }
38
38
  end
39
-
39
+
40
40
  end
41
41
 
42
42
  describe 'precisions' do
43
43
  let(:date) { Date.today }
44
-
44
+
45
45
  it 'has day precision by default' do
46
46
  expect(date).to be_day_precision
47
47
  end
48
-
48
+
49
49
  it '#day_precison returns a new date object' do
50
50
  expect(date.day_precision).not_to equal(date)
51
51
  expect(date.day_precision).to eq(date)
52
52
  end
53
-
53
+
54
54
  end
55
-
56
-
55
+
56
+
57
57
  describe '#negate' do
58
58
  let(:date) { Date.edtf('2004?') }
59
-
59
+
60
60
  it 'returns a new date with the negated year' do
61
61
  expect(date.negate.year).to eq(date.year * -1)
62
62
  end
63
-
63
+
64
64
  it 'returns a new date with the same month' do
65
65
  expect(date.negate.month).to eq(date.month)
66
66
  end
67
-
67
+
68
68
  it 'returns a new date with the same day' do
69
69
  expect(date.negate.day).to eq(date.day)
70
70
  end
71
-
71
+
72
72
  it 'returns a new date with the same precision' do
73
73
  expect(date.negate.precision).to eq(date.precision)
74
74
  end
75
75
  end
76
-
76
+
77
77
  describe '#succ' do
78
-
78
+
79
79
  it 'the successor of 2004 is 2005' do
80
80
  expect(Date.edtf('2004').succ.year).to eq(2005)
81
81
  end
@@ -93,43 +93,43 @@ describe 'Date/DateTime' do
93
93
  end
94
94
 
95
95
  end
96
-
96
+
97
97
  describe '#next' do
98
-
98
+
99
99
  it 'returns the successor when given no argument' do
100
100
  expect(Date.edtf('1999').next[0].year).to eq(2000)
101
101
  end
102
-
102
+
103
103
  it 'returns an array of the next 3 elements when passed 3 as an argument' do
104
104
  Date.edtf('1999').next(3).map(&:year) == [2000, 2001, 2002]
105
105
  end
106
-
106
+
107
107
  end
108
-
109
-
108
+
109
+
110
110
  describe '#change' do
111
111
  let(:date) { Date.edtf('2004-09?~') }
112
112
 
113
113
  it 'returns a copy of the date if given empty option hash' do
114
114
  expect(date.change({})).to eq(date)
115
115
  end
116
-
116
+
117
117
  it 'the returned copy is not identical at object level' do
118
118
  expect(date.change({})).not_to equal(date)
119
119
  end
120
-
120
+
121
121
  describe 'when given a new year' do
122
122
  let(:changeset) { { :year => 1999 } }
123
-
123
+
124
124
  it 'returns a new date instance with the changed year' do
125
125
  expect(date.change(changeset).year).to eq(1999)
126
126
  end
127
-
127
+
128
128
  end
129
129
 
130
130
  describe 'when given a new precision' do
131
131
  let(:changeset) { { :precision => :year } }
132
-
132
+
133
133
  it 'returns a new date instance with the changed precision' do
134
134
  expect(date.change(changeset).precision).to eq(:year)
135
135
  end
@@ -139,13 +139,13 @@ describe 'Date/DateTime' do
139
139
  it 'copies extended values by value' do
140
140
  expect { date.change({}).approximate! }.not_to change { date.approximate? }
141
141
  end
142
-
142
+
143
143
  end
144
-
144
+
145
145
  describe '#uncertain?' do
146
-
146
+
147
147
  let(:date) { Date.new }
148
-
148
+
149
149
  it { expect(Date.new).not_to be_uncertain }
150
150
 
151
151
  [:year, :month, :day].each do |part|
@@ -164,29 +164,29 @@ describe 'Date/DateTime' do
164
164
  expect(date.uncertain?(other)).to eq(false)
165
165
  end
166
166
  end
167
-
167
+
168
168
  end
169
-
169
+
170
170
  end
171
-
171
+
172
172
  describe 'uncertain/approximate hash' do
173
-
173
+
174
174
  it 'is 0 by default' do
175
175
  expect(Date.new().send(:ua_hash)).to eq(0)
176
176
  end
177
-
177
+
178
178
  it 'is 8 for approximate year' do
179
179
  expect(Date.new.approximate!(:year).send(:ua_hash)).to eq(8)
180
180
  end
181
-
181
+
182
182
  end
183
-
183
+
184
184
  describe 'sorting and comparisons' do
185
185
  let(:xmas) { Date.new(2011, 12, 24) }
186
186
  let(:new_years_eve) { Date.new(2011, 12, 31) }
187
-
187
+
188
188
  describe '#values' do
189
-
189
+
190
190
  it 'returns [2011,12,24] for christmas' do
191
191
  expect(xmas.values).to eq([2011,12,24])
192
192
  end
@@ -198,11 +198,11 @@ describe 'Date/DateTime' do
198
198
  it 'returns [2011] for christmas with year precision' do
199
199
  expect(xmas.year_precision!.values).to eq([2011])
200
200
  end
201
-
201
+
202
202
  end
203
-
203
+
204
204
  describe '#<=>' do
205
-
205
+
206
206
  it '2009-12-24 should be less than 2011-12-31' do
207
207
  expect(Date.new(2009,12,24)).to be < Date.new(2011,12,31)
208
208
  end
@@ -214,12 +214,12 @@ describe 'Date/DateTime' do
214
214
  it '2009-12-24 should be less than 2011' do
215
215
  expect(Date.new(2009,12,24)).to be < Date.edtf('2011')
216
216
  end
217
-
218
-
217
+
218
+
219
219
  end
220
-
220
+
221
221
  describe '#==' do
222
-
222
+
223
223
  it "xmas and new year's eve are not equal" do
224
224
  expect(xmas).not_to eq(new_years_eve)
225
225
  end
@@ -231,15 +231,15 @@ describe 'Date/DateTime' do
231
231
  it "xmas and january 24 are not equal using month percision" do
232
232
  expect(xmas.month_precision!).not_to eq(xmas.month_precision!.next)
233
233
  end
234
-
234
+
235
235
 
236
236
  it "xmas and new year's eve are equal using year percision" do
237
237
  expect(xmas.year_precision!).to eq(new_years_eve.year_precision!)
238
238
  end
239
-
239
+
240
240
  end
241
-
241
+
242
242
  end
243
-
244
-
245
- end
243
+
244
+
245
+ end
@@ -132,5 +132,10 @@ module EDTF
132
132
  end
133
133
  end
134
134
 
135
+ it 'may not have an open start' do
136
+ expect(
137
+ proc { Interval.new(:open, Date.today) }
138
+ ).to raise_error(ArgumentError)
139
+ end
135
140
  end
136
- end
141
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edtf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvester Keil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-27 00:00:00.000000000 Z
11
+ date: 2016-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '3.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5.0'
22
+ version: '6.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '3.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5.0'
32
+ version: '6.0'
33
33
  description: A Ruby implementation of the Extended Date/Time Format (EDTF).
34
34
  email:
35
35
  - http://sylvester.keil.or.at