edtf 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/Gemfile +7 -0
- data/LICENSE +26 -0
- data/README.md +81 -0
- data/Rakefile +21 -0
- data/edtf.gemspec +34 -0
- data/features/parser/date_times.feature +35 -0
- data/features/parser/dates.feature +53 -0
- data/features/parser/intervals.feature +19 -0
- data/features/parser/precision.feature +14 -0
- data/features/parser/unspecified.feature +19 -0
- data/features/step_definitions/edtf_steps.rb +80 -0
- data/features/support/env.rb +1 -0
- data/lib/edtf.rb +35 -0
- data/lib/edtf/date.rb +77 -0
- data/lib/edtf/extensions.rb +4 -0
- data/lib/edtf/interval.rb +66 -0
- data/lib/edtf/parser.y +313 -0
- data/lib/edtf/seasons.rb +36 -0
- data/lib/edtf/uncertainty.rb +58 -0
- data/lib/edtf/version.rb +3 -0
- data/spec/edtf/extensions_spec.rb +44 -0
- data/spec/edtf/seasons_spec.rb +59 -0
- data/spec/edtf/uncertainty_spec.rb +114 -0
- data/spec/spec_helper.rb +8 -0
- metadata +148 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright 2011 Sylvester Keil. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
1. Redistributions of source code must retain the above copyright notice,
|
7
|
+
this list of conditions and the following disclaimer.
|
8
|
+
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
|
13
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
|
14
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
15
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
16
|
+
EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
17
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
18
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
19
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
20
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
21
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
22
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
+
|
24
|
+
The views and conclusions contained in the software and documentation are
|
25
|
+
those of the authors and should not be interpreted as representing official
|
26
|
+
policies, either expressed or implied, of the copyright holder.
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
EDTF-Ruby
|
2
|
+
=========
|
3
|
+
|
4
|
+
Ruby implementation of the [Extended Date/Time Format
|
5
|
+
Specification](http://www.loc.gov/standards/datetime/spec.html).
|
6
|
+
|
7
|
+
|
8
|
+
Compatibility
|
9
|
+
-------------
|
10
|
+
|
11
|
+
As of EDTF Specification DRAFT, August 4, 2001:
|
12
|
+
|
13
|
+
* Level 0: fully implemented
|
14
|
+
* Level 1: fully implemented
|
15
|
+
* Level 2: implemented features 204, 207, 208, and 209
|
16
|
+
|
17
|
+
The following level 2 extensions are currently _not_ supported: 201, 202, 203,
|
18
|
+
204, and 205.
|
19
|
+
|
20
|
+
|
21
|
+
Quickstart
|
22
|
+
----------
|
23
|
+
|
24
|
+
EDTF Ruby is implemented as an extension to the regular Ruby date/time classes.
|
25
|
+
You can access parse EDTF strings either using `Date.edtf` or `EDTF.parse`; if
|
26
|
+
given a valid EDTF string the return value will either be an (extended) `Date`,
|
27
|
+
`EDTF::Interval` or `Range` (for masked precision strings) instance.
|
28
|
+
|
29
|
+
$ [sudo] gem install edtf
|
30
|
+
$ irb
|
31
|
+
> require 'edtf'
|
32
|
+
> d = Date.edtf('1984?')
|
33
|
+
> d.uncertain?
|
34
|
+
=> true
|
35
|
+
> d.certain!
|
36
|
+
> d.uncertain?
|
37
|
+
=> false
|
38
|
+
> d = Date.edtf('1999-03-uu')
|
39
|
+
> d.unspecified?
|
40
|
+
=> true
|
41
|
+
> d.unspecified? :year
|
42
|
+
=> false
|
43
|
+
> d.unspecified? :day
|
44
|
+
=> true
|
45
|
+
> Date.edtf('2003-24').winter?
|
46
|
+
=> true
|
47
|
+
> Date.edtf('196x')
|
48
|
+
=> #<Date: 1960-01-01>...#<Date: 1970-01-01>
|
49
|
+
> Date.edtf('y-17e7').year
|
50
|
+
=> -170000000
|
51
|
+
> d = Date.edtf('1984-06?/2004-08?')
|
52
|
+
> d.from.uncertain?
|
53
|
+
=> true
|
54
|
+
> d.each.to_a.length
|
55
|
+
=> 7367 # days between 1984-06 and 2004-08
|
56
|
+
> Date.edtf('2004-01-01/open').open?
|
57
|
+
=> true
|
58
|
+
|
59
|
+
|
60
|
+
For additional features take a look at the rdoc, source, and rspec examples.
|
61
|
+
|
62
|
+
|
63
|
+
Development
|
64
|
+
-----------
|
65
|
+
|
66
|
+
$ git clone https://inukshuk@github.com/inukshuk/edtf-ruby.git
|
67
|
+
$ cd edtf-ruby
|
68
|
+
$ bundle install
|
69
|
+
$ bundle exec rake racc
|
70
|
+
$ bundle exec rspec spec
|
71
|
+
$ bundle exec cucumber
|
72
|
+
|
73
|
+
For extra credit, fork the project on github: pull requests welcome!
|
74
|
+
|
75
|
+
Credits
|
76
|
+
-------
|
77
|
+
|
78
|
+
EDTF-Ruby was written by [Sylvester Keil](http://sylvester.keil.or.at).
|
79
|
+
|
80
|
+
Published under the terms and conditions of the FreeBSD License; see LICENSE
|
81
|
+
for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
require 'rake/clean'
|
3
|
+
|
4
|
+
desc 'Generates the parser'
|
5
|
+
task :racc do
|
6
|
+
system 'bundle exec racc -o lib/edtf/parser.rb lib/edtf/parser.y'
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'Generates the parser with debug information'
|
10
|
+
task :racc_debug do
|
11
|
+
system 'bundle exec racc -v -t -o lib/edtf/parser.rb lib/edtf/parser.y'
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Builds the gem file'
|
15
|
+
task :build => [:racc] do
|
16
|
+
system 'gem build edtf.gemspec'
|
17
|
+
end
|
18
|
+
|
19
|
+
CLEAN.include('lib/edtf/parser.rb')
|
20
|
+
CLEAN.include('lib/edtf/parser.output')
|
21
|
+
CLEAN.include('*.gem')
|
data/edtf.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
|
5
|
+
require 'edtf/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = 'edtf'
|
9
|
+
s.version = EDTF::VERSION.dup
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = ['Sylvester Keil']
|
12
|
+
s.email = ['http://sylvester.keil.or.at']
|
13
|
+
s.homepage = 'http://inukshuk.github.com/edtf-ruby'
|
14
|
+
s.summary = 'Extended Date/Time Format for Ruby.'
|
15
|
+
s.description = 'An Extended Date/Time Format (EDTF) Parser for Ruby.'
|
16
|
+
s.license = 'FreeBSD'
|
17
|
+
|
18
|
+
s.add_development_dependency('rake', ['~>0.9'])
|
19
|
+
s.add_development_dependency('racc', ['~>1.4'])
|
20
|
+
s.add_development_dependency('cucumber', ['~>1.0'])
|
21
|
+
s.add_development_dependency('rspec', ['~>2.6'])
|
22
|
+
s.add_development_dependency('ZenTest', ['~>4.6'])
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n") << 'lib/edtf/parser.rb'
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = []
|
27
|
+
s.require_path = 'lib'
|
28
|
+
|
29
|
+
s.rdoc_options = %w{--line-numbers --inline-source --title "EDTF-Ruby" --main README.md --webcvs=http://github.com/inukshuk/edtf-ruby/tree/master/}
|
30
|
+
s.extra_rdoc_files = %w{README.md LICENSE}
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
# vim: syntax=ruby
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: EDTF parses date/time strings
|
2
|
+
|
3
|
+
As a user of edtf-ruby
|
4
|
+
I want to parse date/time strings formatted in EDTF
|
5
|
+
|
6
|
+
Scenario Outline: EDTF parses a date/time string
|
7
|
+
When I parse the string "<string>"
|
8
|
+
Then the year should be "<year>"
|
9
|
+
And the month should be "<month>"
|
10
|
+
And the day should be "<day>"
|
11
|
+
And the hours should be "<hours>"
|
12
|
+
And the minutes should be "<minutes>"
|
13
|
+
And the seconds should be "<seconds>"
|
14
|
+
|
15
|
+
@002 @level0
|
16
|
+
Scenarios: simple dates
|
17
|
+
| string | year | month | day | hours | minutes | seconds |
|
18
|
+
| 2001-02-03T09:30:01 | 2001 | 2 | 3 | 9 | 30 | 1 |
|
19
|
+
|
20
|
+
|
21
|
+
Scenario Outline: EDTF parses a date/time string with timezone indicator
|
22
|
+
When I parse the string "<string>"
|
23
|
+
Then the year should be "<year>" (UTC)
|
24
|
+
And the month should be "<month>" (UTC)
|
25
|
+
And the day should be "<day>" (UTC)
|
26
|
+
And the hours should be "<hours>" (UTC)
|
27
|
+
And the minutes should be "<minutes>"
|
28
|
+
And the seconds should be "<seconds>"
|
29
|
+
|
30
|
+
@002 @level0
|
31
|
+
Scenarios: date/times with timezone
|
32
|
+
| string | year | month | day | hours | minutes | seconds |
|
33
|
+
| 2004-01-01T10:10:10Z | 2004 | 1 | 1 | 10 | 10 | 10 |
|
34
|
+
| 2004-01-01T10:10:10+05:00 | 2004 | 1 | 1 | 5 | 10 | 10 |
|
35
|
+
| 2004-01-01T02:10:10+05:00 | 2003 | 12 | 31 | 21 | 10 | 10 |
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Feature: EDTF parser parses date strings
|
2
|
+
|
3
|
+
In order to use dates in EDTF
|
4
|
+
As a user of edtf-ruby
|
5
|
+
I want to parse date strings formatted in EDTF
|
6
|
+
|
7
|
+
Scenario Outline: EDTF parses a date string
|
8
|
+
When I parse the string "<string>"
|
9
|
+
Then the year should be "<year>"
|
10
|
+
And the month should be "<month>"
|
11
|
+
And the day should be "<day>"
|
12
|
+
|
13
|
+
@001 @level0
|
14
|
+
Scenarios: simple dates
|
15
|
+
| string | year | month | day |
|
16
|
+
| 2001-02-03 | 2001 | 2 | 3 |
|
17
|
+
| 2008-12 | 2008 | 12 | 1 |
|
18
|
+
| 2008 | 2008 | 1 | 1 |
|
19
|
+
| -0999 | -999 | 1 | 1 |
|
20
|
+
| 0000 | 0 | 1 | 1 |
|
21
|
+
|
22
|
+
|
23
|
+
Scenario Outline: EDTF parses uncertain date strings
|
24
|
+
When I parse the string "<string>"
|
25
|
+
Then the year should be "<year>"
|
26
|
+
And the year should be uncertain? "<uncertain-year>"
|
27
|
+
And the month should be "<month>"
|
28
|
+
And the month should be uncertain? "<uncertain-month>"
|
29
|
+
And the day should be "<day>"
|
30
|
+
And the day should be uncertain? "<uncertain-day>"
|
31
|
+
|
32
|
+
@101 @level1
|
33
|
+
Scenarios: uncertain date examples from the specification
|
34
|
+
| string | year | uncertain-year | month | uncertain-month | day | uncertain-day |
|
35
|
+
| 1992? | 1992 | yes | 1 | yes | 1 | yes |
|
36
|
+
| 1984? | 1984 | yes | 1 | yes | 1 | yes |
|
37
|
+
| 2004-06? | 2004 | yes | 6 | yes | 1 | yes |
|
38
|
+
| 2004-06-11? | 2004 | yes | 6 | yes | 11 | yes |
|
39
|
+
|
40
|
+
|
41
|
+
Scenario Outline: EDTF parses uncertain or approximate date strings
|
42
|
+
When I parse the string "<string>"
|
43
|
+
Then the year should be "<year>"
|
44
|
+
And the month should be "<month>"
|
45
|
+
And the day should be "<day>"
|
46
|
+
And the date should be uncertain? "<uncertain>"
|
47
|
+
And the date should be approximate? "<approximate>"
|
48
|
+
|
49
|
+
@101 @level1
|
50
|
+
Scenarios: uncertain date examples from the specification
|
51
|
+
| string | year | month | day | uncertain | approximate |
|
52
|
+
| 1984~ | 1984 | 1 | 1 | no | yes |
|
53
|
+
| 1984?~ | 1984 | 1 | 1 | yes | yes |
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: EDTF parses ISO 8601 interval strings
|
2
|
+
As a user of edtf-ruby
|
3
|
+
I want to parse ISO 8601 interval strings
|
4
|
+
|
5
|
+
Scenario Outline: parse intervals
|
6
|
+
When I parse the string "<string>"
|
7
|
+
Then the interval should start at "<from>"
|
8
|
+
And the interval should end at "<to>"
|
9
|
+
|
10
|
+
@004 @level0
|
11
|
+
Scenarios: specification intervals
|
12
|
+
| string | from | to |
|
13
|
+
| 1964/2008 | 1964-01-01 | 2008-01-01 |
|
14
|
+
| 2004-06/2006-08 | 2004-06-01 | 2006-08-01 |
|
15
|
+
| 2004-01-01/2004-01-02 | 2004-01-01 | 2004-01-02 |
|
16
|
+
| 2004-02-01/2005-02-08 | 2004-02-01 | 2005-02-08 |
|
17
|
+
| 2004-02-01/2005-02 | 2004-02-01 | 2005-02-01 |
|
18
|
+
| 2004-02-01/2005 | 2004-02-01 | 2005-01-01 |
|
19
|
+
| 2005/2006-02 | 2005-01-01 | 2006-02-01 |
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Parse masked precision strings
|
2
|
+
|
3
|
+
As a user of edtf-ruby
|
4
|
+
I want to parse masked precision strings
|
5
|
+
|
6
|
+
Scenario Outline: Masked precision strings
|
7
|
+
When I parse the string "<string>"
|
8
|
+
Then the duration should range from "<start>" to "<end>"
|
9
|
+
|
10
|
+
@level2 @2041
|
11
|
+
Scenarios: decades and centuries
|
12
|
+
| string | start | end |
|
13
|
+
| 196x | 1960 | 1970 |
|
14
|
+
| 19xx | 1900 | 2000 |
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: Parse unspecified date strings
|
2
|
+
As a user of EDTF-Ruby
|
3
|
+
I want to be able to parse date strings containing unspecified elements
|
4
|
+
|
5
|
+
Scenario Outline: parse unspecified dates
|
6
|
+
When I parse the string "<string>"
|
7
|
+
Then the year should be "<year>"
|
8
|
+
And the month should be "<month>"
|
9
|
+
And the day should be "<day>"
|
10
|
+
And the unspecified string code be "<unspecified>"
|
11
|
+
|
12
|
+
@102 @level1
|
13
|
+
Scenarios: examples from the specification draft
|
14
|
+
| string | year | month | day | unspecified |
|
15
|
+
| 199u | 1990 | 1 | 1 | sssu-ss-ss |
|
16
|
+
| 19uu | 1900 | 1 | 1 | ssuu-ss-ss |
|
17
|
+
| 1999-uu | 1999 | 1 | 1 | ssss-uu-ss |
|
18
|
+
| 1999-02-uu | 1999 | 2 | 1 | ssss-ss-uu |
|
19
|
+
| 1999-uu-uu | 1999 | 1 | 1 | ssss-uu-uu |
|
@@ -0,0 +1,80 @@
|
|
1
|
+
When /^I parse the string "([^"]*)"$/ do |string|
|
2
|
+
@edtf = EDTF.parse(string)
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^the year should be "([^"]*)"$/ do |year|
|
6
|
+
@edtf.year.should == year.to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^the month should be "([^"]*)"$/ do |month|
|
10
|
+
@edtf.month.should == month.to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^the day should be "([^"]*)"$/ do |day|
|
14
|
+
@edtf.day.should == day.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^the hours should be "([^"]*)"$/ do |hours|
|
18
|
+
@edtf.hour.should == hours.to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^the year should be "([^"]*)" \(UTC\)$/ do |year|
|
22
|
+
@edtf.to_time.utc.year.should == year.to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
Then /^the month should be "([^"]*)" \(UTC\)$/ do |month|
|
26
|
+
@edtf.to_time.utc.month.should == month.to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
Then /^the day should be "([^"]*)" \(UTC\)$/ do |day|
|
30
|
+
@edtf.to_time.utc.day.should == day.to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
Then /^the hours should be "([^"]*)" \(UTC\)$/ do |hours|
|
34
|
+
@edtf.to_time.utc.hour.should == hours.to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
Then /^the minutes should be "([^"]*)"$/ do |minutes|
|
39
|
+
@edtf.min.should == minutes.to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
Then /^the seconds should be "([^"]*)"$/ do |seconds|
|
43
|
+
@edtf.sec.should == seconds.to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
Then /^the duration should range from "([^"]*)" to "([^"]*)"$/ do |*expected|
|
47
|
+
[@edtf.begin.year.to_s, @edtf.end.year.to_s].should == expected
|
48
|
+
end
|
49
|
+
|
50
|
+
Then /^the interval should start at "([^"]*)"$/ do |date|
|
51
|
+
@edtf.begin.to_s.should == date
|
52
|
+
end
|
53
|
+
|
54
|
+
Then /^the interval should end at "([^"]*)"$/ do |date|
|
55
|
+
@edtf.end.to_s.should == date
|
56
|
+
end
|
57
|
+
|
58
|
+
Then /^the date should be uncertain\? "([^"]*)"$/ do |arg1|
|
59
|
+
@edtf.uncertain?.should == !!(arg1 =~ /y(es)?/i)
|
60
|
+
end
|
61
|
+
|
62
|
+
Then /^the year should be uncertain\? "([^"]*)"$/ do |arg1|
|
63
|
+
@edtf.uncertain?(:year).should == !!(arg1 =~ /y(es)?/i)
|
64
|
+
end
|
65
|
+
|
66
|
+
Then /^the month should be uncertain\? "([^"]*)"$/ do |arg1|
|
67
|
+
@edtf.uncertain?(:month).should == !!(arg1 =~ /y(es)?/i)
|
68
|
+
end
|
69
|
+
|
70
|
+
Then /^the day should be uncertain\? "([^"]*)"$/ do |arg1|
|
71
|
+
@edtf.uncertain?(:day).should == !!(arg1 =~ /y(es)?/i)
|
72
|
+
end
|
73
|
+
|
74
|
+
Then /^the date should be approximate\? "([^"]*)"$/ do |arg1|
|
75
|
+
@edtf.approximate?.should == !!(arg1 =~ /y(es)?/i)
|
76
|
+
end
|
77
|
+
|
78
|
+
Then /^the unspecified string code be "([^"]*)"$/ do |arg1|
|
79
|
+
@edtf.unspecified.to_s.should == arg1
|
80
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'edtf'
|
data/lib/edtf.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#--
|
2
|
+
# EDTF-Ruby
|
3
|
+
# Copyright 2011 Sylvester Keil. All rights reserved.
|
4
|
+
#++
|
5
|
+
|
6
|
+
require 'date'
|
7
|
+
autoload :Rational, 'rational'
|
8
|
+
|
9
|
+
require 'forwardable'
|
10
|
+
|
11
|
+
require 'edtf/version'
|
12
|
+
require 'edtf/uncertainty'
|
13
|
+
require 'edtf/seasons'
|
14
|
+
require 'edtf/date'
|
15
|
+
require 'edtf/interval'
|
16
|
+
require 'edtf/parser'
|
17
|
+
require 'edtf/extensions'
|
18
|
+
|
19
|
+
# = EDTF-Ruby
|
20
|
+
#
|
21
|
+
# This module extends the Ruby date/time classes to support the Extended
|
22
|
+
# Date/Time Format (EDTF). See the `EDTF::ExtendedDate` module for an
|
23
|
+
# overview of the features added to the Ruby `Date` class.
|
24
|
+
#
|
25
|
+
# To parse EDTF strings use either `Date.edtf` of `EDTF.parse`.
|
26
|
+
#
|
27
|
+
module EDTF
|
28
|
+
|
29
|
+
def parse(input, options = {})
|
30
|
+
::Date.edtf(input, options)
|
31
|
+
end
|
32
|
+
|
33
|
+
module_function :parse
|
34
|
+
|
35
|
+
end
|