iso8601 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,26 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module ISO8601
4
-
4
+ ##
5
5
  # Contains all ISO8601-specific errors.
6
6
  module Errors
7
-
8
- # Error that is raised when unknown pattern is parsed.
7
+ ##
8
+ # Raised when the given pattern doesn't fit as ISO 8601 parser.
9
9
  class UnknownPattern < ::StandardError
10
10
  def initialize(pattern)
11
11
  super("The pattern “#{pattern}” is not allowed in this implementation of ISO8601.")
12
12
  end
13
13
  end
14
- class DurationError < ::StandardError
15
- def initialize(duration)
16
- super("Unexpected type of duration “#{duration}”.")
14
+ ##
15
+ # Raised when the given date is valid but out of range.
16
+ class RangeError < ::StandardError
17
+ def initialize(pattern)
18
+ super("“#{pattern}” is out of range")
17
19
  end
18
20
  end
19
- class DurationBaseError < ISO8601::Errors::DurationError
21
+ ##
22
+ # Raise when the base is not suitable.
23
+ class DurationBaseError < ::StandardError
20
24
  def initialize(duration)
21
25
  super("Wrong base for #{duration} duration.")
22
26
  end
@@ -0,0 +1,115 @@
1
+ module ISO8601
2
+ ##
3
+ # A Time representation
4
+ #
5
+ # @example
6
+ # t = Time.new('10:11:12')
7
+ # t = Time.new('T10:11:12.5Z')
8
+ # t.hour # => 10
9
+ # t.minute # => 11
10
+ # t.second # => 12.5
11
+ # t.zone # => '+00:00'
12
+ class Time
13
+ extend Forwardable
14
+
15
+ def_delegators(:@time,
16
+ :to_time, :to_date, :to_datetime,
17
+ :hour, :minute, :zone)
18
+ ##
19
+ # The separator used in the original ISO 8601 string.
20
+ attr_reader :separator
21
+ ##
22
+ # The second atom
23
+ attr_reader :second
24
+ ##
25
+ # The original atoms
26
+ attr_reader :atoms
27
+ ##
28
+ # @param [String] input The time pattern
29
+ # @param [Date] base The base date to determine the time
30
+ def initialize(input, base = ::Date.today)
31
+ @original = input
32
+
33
+ @atoms = atomize(input)
34
+ @time = ::DateTime.new(*[base.year, base.month, base.day], *@atoms)
35
+ @second = @time.second + @time.second_fraction.to_f
36
+ rescue ArgumentError => error
37
+ raise ISO8601::Errors::RangeError, input
38
+ end
39
+ ##
40
+ # Forwards the time the given amount of seconds.
41
+ #
42
+ # @param [Numeric] seconds The seconds to add
43
+ #
44
+ # @return [ISO8601::Time] New time resulting of the addition
45
+ def +(seconds)
46
+ moment = @time.to_time.localtime(zone) + seconds
47
+ format = moment.subsec.zero? ? "T%H:%M:%S%:z" : "T%H:%M:%S.%16N%:z"
48
+
49
+ ISO8601::Time.new(moment.strftime(format), ::Date.parse(moment.strftime('%Y-%m-%d')))
50
+ end
51
+ ##
52
+ # Backwards the date the given amount of seconds.
53
+ #
54
+ # @param [Numeric] seconds The seconds to remove
55
+ #
56
+ # @return [ISO8601::Time] New time resulting of the substraction
57
+ def -(seconds)
58
+ moment = @time.to_time.localtime(zone) - seconds
59
+ format = moment.subsec.zero? ? "T%H:%M:%S%:z" : "T%H:%M:%S.%16N%:z"
60
+
61
+ ISO8601::Time.new(moment.strftime(format), ::Date.parse(moment.strftime('%Y-%m-%d')))
62
+ end
63
+ ##
64
+ # Converts self to a time component representation.
65
+ def to_s
66
+ strf = @time.second_fraction == 0 ? 'T%H:%M:%S%:z' : 'T%H:%M:%S.%2N%:z'
67
+ @time.strftime(strf)
68
+ end
69
+ ##
70
+ # Converts self to an array of atoms.
71
+ def to_a
72
+ [hour, minute, second, zone]
73
+ end
74
+
75
+ private
76
+ ##
77
+ # Splits the time component into valid atoms.
78
+ # Acceptable patterns: hh, hh:mm or hhmm and hh:mm:ss or hhmmss. Any form
79
+ # can be prepended by `T`.
80
+ #
81
+ # @param [String] input
82
+ #
83
+ # @return [Array<Integer, Float>]
84
+ def atomize(input)
85
+ _, time, zone = /^T?(.+?)(Z|[+-].+)?$/.match(input).to_a
86
+
87
+ _, hour, separator, minute, second = /^(?:
88
+ (\d{2})(:?)(\d{2})\2(\d{2}(?:[.,]\d+)?) |
89
+ (\d{2})(:?)(\d{2}) |
90
+ (\d{2})
91
+ )$/x.match(time).to_a.compact
92
+
93
+ raise ISO8601::Errors::UnknownPattern.new(@original) if hour.nil?
94
+
95
+ @separator = separator
96
+
97
+ hour = hour.to_i
98
+ minute &&= minute.to_i
99
+ second &&= second.to_f
100
+
101
+ raise ISO8601::Errors::UnknownPattern.new(@original) unless valid_zone?(zone)
102
+
103
+ [hour, minute, second, zone].compact
104
+ end
105
+
106
+ def valid_zone?(zone)
107
+ _, offset, separator = /^(Z|[+-]\d{2}(?:(:?)\d{2})?)$/.match(zone).to_a.compact
108
+
109
+ wrong_pattern = !zone.nil? && offset.nil?
110
+ invalid_separators = zone.to_s.match(/^[+-]\d{2}:?\d{2}$/) && (@separator != separator)
111
+
112
+ !(wrong_pattern || invalid_separators)
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,5 @@
1
+ module ISO8601
2
+ ##
3
+ # The gem version
4
+ VERSION = '0.5.0'
5
+ end
@@ -4,20 +4,20 @@ require 'spec_helper'
4
4
 
5
5
  describe ISO8601::Atom do
6
6
  it "should raise a TypeError when receives anything but a Numeric value" do
7
- expect { ISO8601::Atom.new('1') }.to raise_error(TypeError)
8
- expect { ISO8601::Atom.new(true) }.to raise_error(TypeError)
9
- expect { ISO8601::Atom.new(-1.1) }.to_not raise_error(TypeError)
10
- expect { ISO8601::Atom.new(-1) }.to_not raise_error(TypeError)
11
- expect { ISO8601::Atom.new(0) }.to_not raise_error(TypeError)
12
- expect { ISO8601::Atom.new(1) }.to_not raise_error(TypeError)
13
- expect { ISO8601::Atom.new(1.1) }.to_not raise_error(TypeError)
7
+ expect { ISO8601::Atom.new('1') }.to raise_error
8
+ expect { ISO8601::Atom.new(true) }.to raise_error
9
+ expect { ISO8601::Atom.new(-1.1) }.to_not raise_error
10
+ expect { ISO8601::Atom.new(-1) }.to_not raise_error
11
+ expect { ISO8601::Atom.new(0) }.to_not raise_error
12
+ expect { ISO8601::Atom.new(1) }.to_not raise_error
13
+ expect { ISO8601::Atom.new(1.1) }.to_not raise_error
14
14
  end
15
15
  it "should raise a TypeError when receives anything but a ISO8601::DateTime instance or nil" do
16
- expect { ISO8601::Atom.new(1, ISO8601::DateTime.new('2012-07-07')) }.to_not raise_error(TypeError)
17
- expect { ISO8601::Atom.new(1, nil) }.to_not raise_error(TypeError)
18
- expect { ISO8601::Atom.new(1, true) }.to raise_error(TypeError)
19
- expect { ISO8601::Atom.new(1, 'foo') }.to raise_error(TypeError)
20
- expect { ISO8601::Atom.new(1, 10) }.to raise_error(TypeError)
16
+ expect { ISO8601::Atom.new(1, ISO8601::DateTime.new('2012-07-07')) }.to_not raise_error
17
+ expect { ISO8601::Atom.new(1, nil) }.to_not raise_error
18
+ expect { ISO8601::Atom.new(1, true) }.to raise_error
19
+ expect { ISO8601::Atom.new(1, 'foo') }.to raise_error
20
+ expect { ISO8601::Atom.new(1, 10) }.to raise_error
21
21
  end
22
22
  it "should create a new atom" do
23
23
  ISO8601::Atom.new(-1).should be_an_instance_of(ISO8601::Atom)
@@ -42,7 +42,7 @@ end
42
42
  describe ISO8601::Years do
43
43
  describe '#factor' do
44
44
  it "should return the Year factor" do
45
- expect { ISO8601::Years.new(1).factor }.to_not raise_error(NotImplementedError)
45
+ expect { ISO8601::Years.new(1).factor }.to_not raise_error
46
46
  ISO8601::Years.new(2).factor.should == 31536000
47
47
  ISO8601::Years.new(1).factor.should == 31536000
48
48
  end
@@ -75,7 +75,7 @@ end
75
75
  describe ISO8601::Months do
76
76
  describe '#factor' do
77
77
  it "should return the Month factor" do
78
- expect { ISO8601::Months.new(1).factor }.to_not raise_error(NotImplementedError)
78
+ expect { ISO8601::Months.new(1).factor }.to_not raise_error
79
79
  ISO8601::Months.new(2).factor.should == 2628000
80
80
  end
81
81
  it "should return the Month factor for a common year" do
@@ -5,6 +5,7 @@ require 'spec_helper'
5
5
  describe ISO8601::DateTime do
6
6
  it "should raise a ISO8601::Errors::UnknownPattern for any unknown pattern" do
7
7
  expect { ISO8601::DateTime.new('2') }.to raise_error(ISO8601::Errors::UnknownPattern)
8
+ expect { ISO8601::DateTime.new('20') }.to raise_error(ISO8601::Errors::UnknownPattern)
8
9
  expect { ISO8601::DateTime.new('201') }.to raise_error(ISO8601::Errors::UnknownPattern)
9
10
  expect { ISO8601::DateTime.new('2010-') }.to raise_error(ISO8601::Errors::UnknownPattern)
10
11
  expect { ISO8601::DateTime.new('2010-') }.to raise_error(ISO8601::Errors::UnknownPattern)
@@ -16,105 +17,108 @@ describe ISO8601::DateTime do
16
17
  expect { ISO8601::DateTime.new('201-0109') }.to raise_error(ISO8601::Errors::UnknownPattern)
17
18
  expect { ISO8601::DateTime.new('2010-05-09T103012+0400') }.to raise_error(ISO8601::Errors::UnknownPattern)
18
19
  expect { ISO8601::DateTime.new('20100509T10:30:12+04:00') }.to raise_error(ISO8601::Errors::UnknownPattern)
19
- end
20
- it "should raise a RangeError for a correct pattern but an invalid date" do
21
- expect { ISO8601::DateTime.new('2010-01-32') }.to raise_error(RangeError)
22
- expect { ISO8601::DateTime.new('2010-02-30') }.to raise_error(RangeError)
23
- expect { ISO8601::DateTime.new('2010-13-30') }.to raise_error(RangeError)
20
+ expect { ISO8601::DateTime.new('2010-05T10:30:12Z') }.to raise_error(ISO8601::Errors::UnknownPattern)
21
+ expect { ISO8601::DateTime.new('2010T10:30:12Z') }.to raise_error(ISO8601::Errors::UnknownPattern)
22
+ expect { ISO8601::DateTime.new('2014-W15-02T10:11:12Z') }.to raise_error(ISO8601::Errors::UnknownPattern)
24
23
  end
25
24
 
26
- it "should parse the reduced precision year (just the century)" do
27
- expect { ISO8601::DateTime.new('20') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
28
- ISO8601::DateTime.new('20').year.should == 2000
25
+ it "should raise a RangeError for a correct pattern but an invalid date" do
26
+ expect { ISO8601::DateTime.new('2010-01-32') }.to raise_error(ISO8601::Errors::RangeError)
27
+ expect { ISO8601::DateTime.new('2010-02-30') }.to raise_error(ISO8601::Errors::RangeError)
28
+ expect { ISO8601::DateTime.new('2010-13-30') }.to raise_error(ISO8601::Errors::RangeError)
29
+ expect { ISO8601::DateTime.new('2010-12-30T25:00:00') }.to raise_error(ISO8601::Errors::RangeError)
29
30
  end
30
31
 
31
32
  it "should parse any allowed pattern" do
32
- expect { ISO8601::DateTime.new('2010') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
33
- expect { ISO8601::DateTime.new('2010-05') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
34
- expect { ISO8601::DateTime.new('2010-05-09') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
35
- expect { ISO8601::DateTime.new('2010-05-09T10') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
36
- expect { ISO8601::DateTime.new('2010-05-09T10:30') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
37
- expect { ISO8601::DateTime.new('2010-05-09T10:30:12') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
38
- expect { ISO8601::DateTime.new('2010-05-09T10:30:12Z') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
39
- expect { ISO8601::DateTime.new('2010-05-09T10:30:12+04') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
40
- expect { ISO8601::DateTime.new('2010-05-09T10:30:12+04:00') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
41
- expect { ISO8601::DateTime.new('2010-05-09T10:30:12-04:00') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
33
+ expect { ISO8601::DateTime.new('2010') }.to_not raise_error
34
+ expect { ISO8601::DateTime.new('2010-05') }.to_not raise_error
35
+ expect { ISO8601::DateTime.new('2010-05-09') }.to_not raise_error
36
+ expect { ISO8601::DateTime.new('2010-05-09T10') }.to_not raise_error
37
+ expect { ISO8601::DateTime.new('2010-05-09T10:30') }.to_not raise_error
38
+ expect { ISO8601::DateTime.new('2010-05-09T10:30:12') }.to_not raise_error
39
+ expect { ISO8601::DateTime.new('2010-05-09T10:30:12Z') }.to_not raise_error
40
+ expect { ISO8601::DateTime.new('2010-05-09T10:30:12+04') }.to_not raise_error
41
+ expect { ISO8601::DateTime.new('2010-05-09T10:30:12+04:00') }.to_not raise_error
42
+ expect { ISO8601::DateTime.new('2010-05-09T10:30:12-04:00') }.to_not raise_error
43
+ expect { ISO8601::DateTime.new('2010-05-09T10:30:12-00:00') }.to_not raise_error
44
+ expect { ISO8601::DateTime.new('-2014-05-31T16:26:00Z') }.to_not raise_error
45
+ expect { ISO8601::DateTime.new('2014-05-31T16:26:10.5Z') }.to_not raise_error
46
+ expect { ISO8601::DateTime.new('2014-05-31T16:26:10,5Z') }.to_not raise_error
47
+ expect { ISO8601::DateTime.new('T10:30:12Z') }.to_not raise_error
48
+ expect { ISO8601::DateTime.new('2014-001') }.to_not raise_error
49
+ expect { ISO8601::DateTime.new('2014121') }.to_not raise_error
50
+ expect { ISO8601::DateTime.new('2014-121T10:11:12Z') }.to_not raise_error
51
+ expect { ISO8601::DateTime.new('20100509T103012+0400') }.to_not raise_error
52
+ expect { ISO8601::DateTime.new('20100509') }.to_not raise_error
53
+ expect { ISO8601::DateTime.new('T103012+0400') }.to_not raise_error
54
+ expect { ISO8601::DateTime.new('T103012+04') }.to_not raise_error
55
+ expect { ISO8601::DateTime.new('T103012+04') }.to_not raise_error
42
56
  end
43
- it "should parse correctly any allowed reduced pattern" do
44
- expect { ISO8601::DateTime.new('20') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
45
- #expect { ISO8601::DateTime.new('201005') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
46
- #ISO8601::DateTime.new('201005').year.should == 2000
47
- #ISO8601::DateTime.new('201005').month.should == 10
48
- #ISO8601::DateTime.new('201005').day.should == 5
49
-
50
- expect { ISO8601::DateTime.new('20100509') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
51
- ISO8601::DateTime.new('20100509').year.should == 2010
52
- ISO8601::DateTime.new('20100509').month.should == 5
53
- ISO8601::DateTime.new('20100509').day.should == 9
54
57
 
55
- expect { ISO8601::DateTime.new('20100509T103012') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
56
- expect { ISO8601::DateTime.new('20100509T103012Z') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
57
- expect { ISO8601::DateTime.new('20100509T103012+04') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
58
- expect { ISO8601::DateTime.new('20100509T103012+0400') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
59
- expect { ISO8601::DateTime.new('20100509T103012-0400') }.to_not raise_error(ISO8601::Errors::UnknownPattern)
58
+ context 'reduced patterns' do
59
+ it "should parse correctly reduced dates" do
60
+ reduced_date = ISO8601::DateTime.new('20100509')
61
+ reduced_date.year.should == 2010
62
+ reduced_date.month.should == 5
63
+ reduced_date.day.should == 9
64
+ end
65
+ it "should parse correctly reduced times" do
66
+ reduced_time = ISO8601::DateTime.new('T101112Z')
67
+ reduced_time.hour.should == 10
68
+ reduced_time.minute.should == 11
69
+ reduced_time.second.should == 12
70
+ end
71
+ it "should parse correctly reduced date times" do
72
+ reduced_datetime = ISO8601::DateTime.new('20140531T101112Z')
73
+ reduced_datetime.year.should == 2014
74
+ reduced_datetime.month.should == 5
75
+ reduced_datetime.day.should == 31
76
+ reduced_datetime.hour.should == 10
77
+ reduced_datetime.minute.should == 11
78
+ reduced_datetime.second.should == 12
79
+ end
60
80
  end
61
81
 
62
82
  it "should return each atomic value" do
63
83
  dt = ISO8601::DateTime.new('2010-05-09T12:02:01+04:00')
64
- dt.century.should == 20
65
84
  dt.year.should == 2010
66
85
  dt.month.should == 5
67
86
  dt.day.should == 9
68
87
  dt.hour.should == 12
69
88
  dt.minute.should == 2
70
89
  dt.second.should == 1
71
- dt.timezone[:full].should == '+04:00'
72
- dt.timezone[:sign].should == '+'
73
- dt.timezone[:hour].should == 4
74
- dt.timezone[:minute].should == 0
75
- dt = ISO8601::DateTime.new('2010-05-09T10Z')
76
- dt.century.should == 20
77
- dt.year.should == 2010
78
- dt.month.should == 5
79
- dt.day.should == 9
80
- dt.hour.should == 10
81
- dt.minute.should == nil
82
- dt.second.should == nil
83
- dt.timezone[:full].should == 0
84
- dt.timezone[:sign].should == nil
85
- dt.timezone[:hour].should == 0
86
- dt.timezone[:minute].should == 0
90
+ dt.zone.should == '+04:00'
87
91
  end
88
- describe '#to_s' do
89
- it "should return the string representation" do
90
- ISO8601::DateTime.new('2010-05-09').to_s.should == '2010-05-09'
91
- end
92
+
93
+ it "should return the right sign for the given year" do
94
+ ISO8601::DateTime.new('-2014-05-31T16:26:00Z').year.should == -2014
95
+ ISO8601::DateTime.new('+2014-05-31T16:26:00Z').year.should == 2014
92
96
  end
93
- describe '#to_time' do
94
- it "should return a Time instance" do
95
- ISO8601::DateTime.new('20').to_time.should be_an_instance_of(Time)
96
- ISO8601::DateTime.new('2010').to_time.should be_an_instance_of(Time)
97
- ISO8601::DateTime.new('2010-05').to_time.should be_an_instance_of(Time)
98
- ISO8601::DateTime.new('2010-05-09').to_time.should be_an_instance_of(Time)
99
- ISO8601::DateTime.new('2010-05-09T12').to_time.should be_an_instance_of(Time)
100
- ISO8601::DateTime.new('2010-05-09T12:02').to_time.should be_an_instance_of(Time)
101
- ISO8601::DateTime.new('2010-05-09T12:02:01').to_time.should be_an_instance_of(Time)
102
- ISO8601::DateTime.new('2010-05-09T12:02:01+04').to_time.should be_an_instance_of(Time)
103
- ISO8601::DateTime.new('2010-05-09T12:02:01+04:00').to_time.should be_an_instance_of(Time)
104
- ISO8601::DateTime.new('2010-05-09T12:02:01-04:00').to_time.should be_an_instance_of(Time)
105
- end
97
+
98
+ it "should respond to delegated casting methods" do
99
+ dt = ISO8601::DateTime.new('2014-12-11T10:09:08Z')
100
+ dt.should respond_to(:to_s, :to_time, :to_date, :to_datetime)
106
101
  end
107
102
 
108
103
  describe '#+' do
109
104
  it "should return the result of the addition" do
110
- (ISO8601::DateTime.new('2012-07-07T20:20:20Z') + 10).to_time.should == ISO8601::DateTime.new('2012-07-07T20:20:30Z').to_time
105
+ (ISO8601::DateTime.new('2012-07-07T20:20:20Z') + 10).to_s.should == '2012-07-07T20:20:30+00:00'
106
+ (ISO8601::DateTime.new('2012-07-07T20:20:20.5Z') + 10).to_s.should == '2012-07-07T20:20:30.50+00:00'
107
+ (ISO8601::DateTime.new('2012-07-07T20:20:20+02:00') + 10).to_s.should == '2012-07-07T20:20:30+02:00'
111
108
  end
112
109
  end
113
110
 
114
111
  describe '#-' do
115
112
  it "should return the result of the substraction" do
116
- (ISO8601::DateTime.new('2012-07-07T20:20:20Z') - 10).to_time.should == ISO8601::DateTime.new('2012-07-07T20:20:10+00:00').to_time
113
+ (ISO8601::DateTime.new('2012-07-07T20:20:20Z') - 10).to_s.should == '2012-07-07T20:20:10+00:00'
117
114
  end
118
115
  end
119
116
 
117
+ describe '#to_a' do
118
+ it "should return an array of atoms" do
119
+ dt = ISO8601::DateTime.new('2014-05-31T19:29:39Z').to_a
120
+ dt.should be_kind_of(Array)
121
+ dt.should == [2014, 5, 31, 19, 29, 39, '+00:00']
122
+ end
123
+ end
120
124
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe ISO8601::Date do
4
+ it "should raise an error for any unknown pattern" do
5
+ expect { ISO8601::Date.new('2') }.to raise_error(ISO8601::Errors::UnknownPattern)
6
+ expect { ISO8601::Date.new('20') }.to raise_error(ISO8601::Errors::UnknownPattern)
7
+ expect { ISO8601::Date.new('201') }.to raise_error(ISO8601::Errors::UnknownPattern)
8
+ expect { ISO8601::Date.new('2010-') }.to raise_error(ISO8601::Errors::UnknownPattern)
9
+ expect { ISO8601::Date.new('2010-') }.to raise_error(ISO8601::Errors::UnknownPattern)
10
+ expect { ISO8601::Date.new('20-05') }.to raise_error(ISO8601::Errors::UnknownPattern)
11
+ expect { ISO8601::Date.new('2010-0') }.to raise_error(ISO8601::Errors::UnknownPattern)
12
+ expect { ISO8601::Date.new('2010-0-09') }.to raise_error(ISO8601::Errors::UnknownPattern)
13
+ expect { ISO8601::Date.new('2010-1-09') }.to raise_error(ISO8601::Errors::UnknownPattern)
14
+ expect { ISO8601::Date.new('201001-09') }.to raise_error(ISO8601::Errors::UnknownPattern)
15
+ expect { ISO8601::Date.new('201-0109') }.to raise_error(ISO8601::Errors::UnknownPattern)
16
+ expect { ISO8601::Date.new('2014-W15-02') }.to raise_error(ISO8601::Errors::UnknownPattern)
17
+ end
18
+
19
+ it "should raise an error for a correct pattern but an invalid date" do
20
+ expect { ISO8601::Date.new('2010-01-32') }.to raise_error(ISO8601::Errors::RangeError)
21
+ expect { ISO8601::Date.new('2010-02-30') }.to raise_error(ISO8601::Errors::RangeError)
22
+ expect { ISO8601::Date.new('2010-13-30') }.to raise_error(ISO8601::Errors::RangeError)
23
+ end
24
+
25
+ it "should parse any allowed pattern" do
26
+ expect { ISO8601::Date.new('2010') }.to_not raise_error
27
+ expect { ISO8601::Date.new('2010-05') }.to_not raise_error
28
+ expect { ISO8601::Date.new('2010-05-09') }.to_not raise_error
29
+ expect { ISO8601::Date.new('2014-001') }.to_not raise_error
30
+ expect { ISO8601::Date.new('2014121') }.to_not raise_error
31
+ expect { ISO8601::Date.new('2014-W15') }.to_not raise_error
32
+ expect { ISO8601::Date.new('2014-W15-2') }.to_not raise_error
33
+ expect { ISO8601::Date.new('2014W15') }.to_not raise_error
34
+ expect { ISO8601::Date.new('2014W152') }.to_not raise_error
35
+ end
36
+
37
+ context 'reduced patterns' do
38
+ it "should parse correctly reduced dates" do
39
+ reduced_date = ISO8601::Date.new('20100509')
40
+ reduced_date.year.should == 2010
41
+ reduced_date.month.should == 5
42
+ reduced_date.day.should == 9
43
+ end
44
+ end
45
+
46
+ it "should return the right sign for the given year" do
47
+ ISO8601::Date.new('-2014-05-31').year.should == -2014
48
+ ISO8601::Date.new('+2014-05-31').year.should == 2014
49
+ end
50
+
51
+ it "should respond to delegated casting methods" do
52
+ dt = ISO8601::Date.new('2014-12-11')
53
+ dt.should respond_to(:to_s, :to_time, :to_date, :to_datetime)
54
+ end
55
+
56
+ describe '#+' do
57
+ it "should return the result of the addition" do
58
+ (ISO8601::Date.new('2012-07-07') + 7).to_s.should == '2012-07-14'
59
+ end
60
+ end
61
+
62
+ describe '#-' do
63
+ it "should return the result of the substraction" do
64
+ (ISO8601::Date.new('2012-07-07') - 7).to_s.should == '2012-06-30'
65
+ end
66
+ end
67
+
68
+ describe '#to_a' do
69
+ it "should return an array of atoms" do
70
+ dt = ISO8601::Date.new('2014-05-31').to_a
71
+ dt.should be_kind_of(Array)
72
+ dt.should == [2014, 5, 31]
73
+ end
74
+ end
75
+
76
+ describe '#atoms' do
77
+ it "should return an array of original atoms" do
78
+ ISO8601::Date.new('2014-05-02').atoms.should == [2014, 5, 2]
79
+ ISO8601::Date.new('2014-05').atoms.should == [2014, 5]
80
+ ISO8601::Date.new('2014').atoms.should == [2014]
81
+ end
82
+ end
83
+ end