magic_date_parser 0.0.1
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/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +40 -0
- data/Rakefile +2 -0
- data/lib/magic_date_parser.rb +138 -0
- data/lib/magic_date_parser/version.rb +3 -0
- data/magic_date_parser.gemspec +17 -0
- data/spec/magic_date_parser_spec.rb +58 -0
- data/spec/spec_helper.rb +1 -0
- metadata +58 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Joshua Hou
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# MagicDateParser
|
2
|
+
|
3
|
+
Parses a string representation of a date range and returns a start and end date. Returns nil when string is not
|
4
|
+
parsable.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'magic_date_parser'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install magic_date_parser
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
```
|
23
|
+
require 'magic_date_parser'
|
24
|
+
|
25
|
+
start, end = MagicDateParser.range("December 4 - 7, 2007")
|
26
|
+
\# [#<Date: 2007-12-04 ((2454439j,0s,0n),+0s,2299161j)>, #<Date: 2007-12-07 ((2454442j,0s,0n),+0s,2299161j)>]
|
27
|
+
|
28
|
+
start, end = MagicDateParser.range("2008/January 2009")
|
29
|
+
\# [#<Date: 2008-01-01 ((2454467j,0s,0n),+0s,2299161j)>, #<Date: 2009-01-31 ((2454863j,0s,0n),+0s,2299161j)>]
|
30
|
+
```
|
31
|
+
|
32
|
+
See `spec/magic\_date\_parser\_spec.rb` for more examples.
|
33
|
+
|
34
|
+
## Contributing
|
35
|
+
|
36
|
+
1. Fork it
|
37
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
38
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
39
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
40
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require "magic_date_parser/version"
|
2
|
+
|
3
|
+
module MagicDateParser
|
4
|
+
def self.range(raw, backup = "")
|
5
|
+
start, finish = try_all_formats(raw)
|
6
|
+
|
7
|
+
backup_date = date(backup)
|
8
|
+
|
9
|
+
start ||= backup_date
|
10
|
+
finish ||= backup_date
|
11
|
+
return start, finish
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse(raw, backup = "")
|
15
|
+
range(raw, backup)[0]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.try_all_formats raw
|
19
|
+
parser = DateWrapper.new raw
|
20
|
+
|
21
|
+
formats.each do |format|
|
22
|
+
begin
|
23
|
+
result = parser.send format
|
24
|
+
return result unless result.nil?
|
25
|
+
rescue NoMethodError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
[nil, nil]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.formats
|
33
|
+
[
|
34
|
+
:month_format,
|
35
|
+
:year_slash_year,
|
36
|
+
:summer_year,
|
37
|
+
:month_and_year_only,
|
38
|
+
:just_a_year,
|
39
|
+
:format_range_same_year,
|
40
|
+
:format_month_range_same_year,
|
41
|
+
:raw_range,
|
42
|
+
:timestamp
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.date(value)
|
47
|
+
begin
|
48
|
+
Date.parse(value)
|
49
|
+
rescue
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class DateWrapper
|
56
|
+
def initialize raw
|
57
|
+
@raw = raw
|
58
|
+
end
|
59
|
+
|
60
|
+
def date value
|
61
|
+
MagicDateParser.date(value)
|
62
|
+
end
|
63
|
+
|
64
|
+
def timestamp
|
65
|
+
if (@raw.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/))
|
66
|
+
day = date(@raw)
|
67
|
+
[day, day]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def month_format
|
72
|
+
if @raw.match(/([A-Za-z]+)\s*-\s*(\w+).*(\d{4})\s*$/)
|
73
|
+
[date("#{$1} #{$3}"), end_of_month(date("#{$2} #{$3}"))]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def month_and_year_only
|
78
|
+
if @raw.match(/^(\S+)\s*(\d{4})$/)
|
79
|
+
start_of_month = date(@raw)
|
80
|
+
[start_of_month, end_of_month(start_of_month)]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def summer_year
|
85
|
+
if @raw.match(/Summer\D*(\d{4})/)
|
86
|
+
[date("June 21, #{$1}"), date("September 21, #{$1}")]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def just_a_year
|
91
|
+
if @raw.match(/^\D*(\d{4})\s?$/)
|
92
|
+
start = Date.civil($1.to_i)
|
93
|
+
[start, end_of_year(start)]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def year_slash_year
|
98
|
+
if @raw.match(/(\d{4})\/(\D*)(\d{4})/)
|
99
|
+
start = Date.civil($1.to_i)
|
100
|
+
finish = end_of_month(date("#{$2} #{$3}"))
|
101
|
+
[start, finish]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def format_month_range_same_year
|
106
|
+
if @raw.match(/(\S+)\s+(\d+)\s*-\s*(\d+), (\d{4})/)
|
107
|
+
[date("#{$1} #{$2}, #{$4}"), date("#{$1} #{$3}, #{$4}")]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def format_range_same_year
|
112
|
+
if @raw.match(/(\w+)\s+(\d+)\s?-\s?(\S+)\s+(\d+), (\d{4})/)
|
113
|
+
[date("#{$1} #{$2}, #{$5}"), date("#{$3} #{$4}, #{$5}")]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def raw_range
|
118
|
+
if @raw.match(/-/)
|
119
|
+
@raw.split('-').map { |value| date(value) }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
def end_of_month(date)
|
125
|
+
@month_days ||= [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
126
|
+
if date.month == 2
|
127
|
+
day = Date.gregorian_leap?(date.year) ? 29 : 28
|
128
|
+
else
|
129
|
+
day = @month_days[date.month - 1]
|
130
|
+
end
|
131
|
+
|
132
|
+
Date.new(date.year, date.month, day)
|
133
|
+
end
|
134
|
+
|
135
|
+
def end_of_year(date)
|
136
|
+
Date.new(date.year, 12, 31)
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/magic_date_parser/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Substantial"]
|
6
|
+
gem.description = %q{Parses a string representation of a date range and returns a start and end date.}
|
7
|
+
gem.summary = %q{Parses a string representation of a date range (for example, "December 4 - 7, 1969") and
|
8
|
+
and returns a list containing a start date and end date.}
|
9
|
+
gem.homepage = "https://github.com/substantial/magic-date-parser"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "magic_date_parser"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = MagicDateParser::VERSION
|
17
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MagicDateParser do
|
4
|
+
examples = [
|
5
|
+
["May 16, 2004 - April 18, 2005", ["2004-05-16", "2005-04-18"]],
|
6
|
+
["December 29, 1959-January 16, 1960", ["1959-12-29", "1960-01-16"]],
|
7
|
+
["February 13-March 6, 1960", ["1960-02-13", "1960-03-06"]],
|
8
|
+
["December 2-20, 1958", ["1958-12-2","1958-12-20"]],
|
9
|
+
["December 4 - 7, 2008", ["2008-12-4", "2008-12-07"]],
|
10
|
+
["February 7 - March 7, 1992", ["1992-02-07", "1992-03-07"]],
|
11
|
+
|
12
|
+
["October 22, 2009 - January 16, 2010", ["2009-10-22", "2010-01-16"]],
|
13
|
+
["May 14 - June 15, 2008", ["2008-05-14", "2008-06-15"]],
|
14
|
+
["June 2007", ["2007-06-01", "2007-06-30"]],
|
15
|
+
["2006", ["2006-01-01", "2006-12-31"]],
|
16
|
+
["July 1- August 21, 2010", ["2010-07-01","2010-08-21"]],
|
17
|
+
["August - November 2008", ["2008-08-01", "2008-11-30"]],
|
18
|
+
|
19
|
+
["September 2 - October 3, 2010 TBC", ["2010-09-02", "2010-10-03"]],
|
20
|
+
["November 3 - December 2, 2000 (extended through March 2, 2001)",
|
21
|
+
["2000-11-03", "2000-12-2"]],
|
22
|
+
["Dates TBC 2009", ["2009-01-01", "2009-12-31"]],
|
23
|
+
["2008/January 2009",["2008-01-01", "2009-1-31"]],
|
24
|
+
["2008/March 2009",["2008-01-01", "2009-3-31"]],
|
25
|
+
["Summer 2001", ["2001-06-21", "2001-09-21"]]
|
26
|
+
]
|
27
|
+
|
28
|
+
examples.each do |example|
|
29
|
+
raw = example[0]
|
30
|
+
expected_start = Date.parse(example[1][0])
|
31
|
+
expected_finish = Date.parse(example[1][1])
|
32
|
+
it "parses '#{raw}' as #{expected_start} -> #{expected_finish}" do
|
33
|
+
start, finish = MagicDateParser.range(raw)
|
34
|
+
start.should == expected_start
|
35
|
+
finish.should == expected_finish
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should fall back to the second date string if the first fails" do
|
40
|
+
start, finish = MagicDateParser.range("", "2009-01-22T00:00:00")
|
41
|
+
start.should == Date.parse("2009-01-22")
|
42
|
+
finish.should == Date.parse("2009-01-22")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not support 'movember'" do
|
46
|
+
start, finish = MagicDateParser.range("April 6-Movember 26, 2007","2007-04-06T00:00:00")
|
47
|
+
start.should == Date.parse("2007-04-06")
|
48
|
+
finish.should == start
|
49
|
+
end
|
50
|
+
|
51
|
+
describe ".parse" do
|
52
|
+
it "should return the first results of .range" do
|
53
|
+
MagicDateParser.stub(:range){[13,17]}
|
54
|
+
MagicDateParser.parse("foo").should == 13
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'magic_date_parser'
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: magic_date_parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Substantial
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-25 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Parses a string representation of a date range and returns a start and
|
15
|
+
end date.
|
16
|
+
email:
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/magic_date_parser.rb
|
27
|
+
- lib/magic_date_parser/version.rb
|
28
|
+
- magic_date_parser.gemspec
|
29
|
+
- spec/magic_date_parser_spec.rb
|
30
|
+
- spec/spec_helper.rb
|
31
|
+
homepage: https://github.com/substantial/magic-date-parser
|
32
|
+
licenses: []
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.8.24
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: Parses a string representation of a date range (for example, "December 4
|
55
|
+
- 7, 1969") and and returns a list containing a start date and end date.
|
56
|
+
test_files:
|
57
|
+
- spec/magic_date_parser_spec.rb
|
58
|
+
- spec/spec_helper.rb
|