iso8601 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a046b00234ecd1ead9531234435f3b28bb1e89d3
4
- data.tar.gz: 53e15b12514e255b2a5aaeb451e041047b2d6ef0
3
+ metadata.gz: ebc324dddf45972ba0a794b182d1cc9057aba93a
4
+ data.tar.gz: df0e9923948069eff193d5cad7db26e244bb25aa
5
5
  SHA512:
6
- metadata.gz: 4be163f63f8e4d488ecb8d6c997e17031445ab0b124644f8c0b6d33ac60cbc9b9b21f5009ba0a185f8cb08cbc7e4a3de9900c9fdccf3589fd75ea5a6cb8e2d99
7
- data.tar.gz: a10fa5e91adbd1717954b81809cdf206e34f676f07f27add1cceb1530d782c7a3df5b5e8052265f10f915578538f3417c8f7890d97fe4bceedf11d2b0061ae22
6
+ metadata.gz: d475f9aa2193aeb8d1e935fb2b74aaeb98112184d5e3d95243d10768bc10799327a130e57def52791bf0a310de16ae5703962cb7ee8d23e8a3a56ec06b9f6f6c
7
+ data.tar.gz: d8e4f640791540d73a3388d11c2a4cbf01379cf34db30324b6e83fadf69213be7e099465edb1860387498d0d7221a064b2bf3829379dd37b07a7bb4f58eb15ae
@@ -0,0 +1,38 @@
1
+ Documentation:
2
+ Enabled: false
3
+
4
+ Lint/UselessComparison:
5
+ Enabled: false
6
+
7
+ Metrics/ClassLength:
8
+ Max: 150
9
+
10
+ # Work in progress
11
+ Metrics/LineLength:
12
+ Max: 183
13
+
14
+ # Work in progress
15
+ Metrics/MethodLength:
16
+ Max: 24
17
+
18
+ # Work in progress
19
+ Metrics/PerceivedComplexity:
20
+ Max: 8
21
+
22
+ Style/Blocks:
23
+ Enabled: false
24
+
25
+ Style/NumericLiterals:
26
+ MinDigits: 10
27
+
28
+ Style/RegexpLiteral:
29
+ MaxSlashes: 0
30
+
31
+ Style/StringLiterals:
32
+ Enabled: false
33
+
34
+ Style/Encoding:
35
+ EnforcedStyle: when_needed
36
+
37
+ Style/BracesAroundHashParameters:
38
+ EnforcedStyle: braces
@@ -3,5 +3,16 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.2
6
- - rbx-2.2.10
6
+ - ruby-head
7
+ - rbx-2
8
+ - jruby-head
7
9
  script: bundle exec rspec spec
10
+ matrix:
11
+ include:
12
+ - rvm: jruby
13
+ env: JRUBY_OPTS='--2.0'
14
+ allow_failures:
15
+ - rvm: jruby-head
16
+ - rvm: ruby-head
17
+ - rvm: rbx-2
18
+ fast_finish: true
@@ -1,3 +1,7 @@
1
+ ## 0.8.1
2
+
3
+ * Fix durations using comma (,) as a decimal separator.
4
+
1
5
  ## 0.8.0
2
6
 
3
7
  * `DateTime` has hash identity by value.
data/Gemfile CHANGED
@@ -1,8 +1,3 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
-
5
- group :doc do
6
- gem 'yard'
7
- gem 'redcarpet'
8
- end
data/README.md CHANGED
@@ -8,6 +8,8 @@ times) standard.
8
8
 
9
9
  [![Build Status](https://secure.travis-ci.org/arnau/ISO8601.png?branch=master)](http://travis-ci.org/arnau/ISO8601/)
10
10
 
11
+ [![Dependency Status](https://gemnasium.com/arnau/ISO8601.svg)](https://gemnasium.com/arnau/ISO8601)
12
+
11
13
  ## Supported versions
12
14
 
13
15
  * MRI 1.9.3
@@ -22,8 +24,8 @@ Check the [changelog](https://github.com/arnau/ISO8601/blob/master/CHANGELOG.md)
22
24
 
23
25
  ### Duration sign
24
26
 
25
- Because Durations and DateTime has a substraction method, Durations has
26
- sign to be able to represent a negative value:
27
+ Because `Durations` and `DateTime` have a substraction method, `Durations` has
28
+ sign to be able to represent negative values:
27
29
 
28
30
  (ISO8601::Duration.new('PT10S') - ISO8601::Duration.new('PT12S')).to_s #=> '-PT2S'
29
31
  (ISO8601::Duration.new('-PT10S') + ISO8601::Duration.new('PT12S')).to_s #=> 'PT2S'
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- $:.push File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
4
4
  require 'iso8601/version'
5
5
 
6
6
  Gem::Specification.new do |s|
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
12
12
  s.homepage = 'https://github.com/arnau/ISO8601'
13
13
  s.summary = "Ruby parser to work with ISO 8601 dateTimes and durations - http://en.wikipedia.org/wiki/ISO_8601"
14
14
  s.description = <<-EOD
15
- ISO8601 is a simple implementation in Ruby of the ISO 8601 (Data elements and
16
- interchange formats - Information interchange - Representation of dates
15
+ ISO8601 is a simple implementation in Ruby of the ISO 8601 (Data elements and
16
+ interchange formats - Information interchange - Representation of dates
17
17
  and times) standard.
18
18
  EOD
19
19
  s.license = 'MIT'
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.require_paths = ['lib']
25
25
 
26
26
  s.has_rdoc = 'yard'
27
-
27
+ s.required_ruby_version = '>= 1.9.3'
28
28
  s.add_development_dependency 'rspec', '~> 3.1'
29
- s.add_development_dependency 'rerun', '~> 0'
29
+ s.add_development_dependency 'rubocop', '~> 0.26'
30
30
  end
@@ -10,9 +10,9 @@ module ISO8601
10
10
  # @param [Numeric] atom The atom value
11
11
  # @param [ISO8601::DateTime, nil] base (nil) The base datetime to compute
12
12
  # the atom factor.
13
- def initialize(atom, base=nil)
14
- raise TypeError, "The atom argument for #{self.inspect} should be a Numeric value." unless atom.kind_of?(Numeric)
15
- raise TypeError, "The base argument for #{self.inspect} should be a ISO8601::DateTime instance or nil." unless base.kind_of?(ISO8601::DateTime) || base.nil?
13
+ def initialize(atom, base = nil)
14
+ fail TypeError, "The atom argument for #{inspect} should be a Numeric value." unless atom.is_a?(Numeric)
15
+ fail TypeError, "The base argument for #{inspect} should be a ISO8601::DateTime instance or nil." unless base.is_a?(ISO8601::DateTime) || base.nil?
16
16
  @atom = atom
17
17
  @base = base
18
18
  end
@@ -55,18 +55,18 @@ module ISO8601
55
55
  atom * factor
56
56
  end
57
57
  ##
58
- # @param [#hash] contrast The contrast to compare against
58
+ # @param [#hash] other The contrast to compare against
59
59
  #
60
60
  # @return [Boolean]
61
- def ==(contrast)
62
- (hash == contrast.hash)
61
+ def ==(other)
62
+ (hash == other.hash)
63
63
  end
64
64
  ##
65
- # @param [#hash] contrast The contrast to compare against
65
+ # @param [#hash] other The contrast to compare against
66
66
  #
67
67
  # @return [Boolean]
68
- def eql?(contrast)
69
- (hash == contrast.hash)
68
+ def eql?(other)
69
+ (hash == other.hash)
70
70
  end
71
71
  ##
72
72
  # @return [Fixnum]
@@ -76,26 +76,27 @@ module ISO8601
76
76
  ##
77
77
  # The atom factor to compute the amount of seconds for the atom
78
78
  def factor
79
- raise NotImplementedError, "The #factor method should be implemented by each subclass"
79
+ fail NotImplementedError,
80
+ "The #factor method should be implemented by each subclass"
80
81
  end
81
82
  end
82
83
  ##
83
84
  # A Years atom in a {ISO8601::Duration}
84
85
  #
85
- # A calendar year is the cyclic time interval in a calendar which is
86
+ # A "calendar year" is the cyclic time interval in a calendar which is
86
87
  # required for one revolution of the Earth around the Sun and approximated to
87
- # an integral number of calendar days”.
88
+ # an integral number of "calendar days".
88
89
  #
89
- # A duration year is the duration of 365 or 366 calendar days depending on
90
- # the start and/or the end of the corresponding time interval within the
91
- # specific calendar year”.
90
+ # A "duration year" is the duration of 365 or 366 "calendar days" depending
91
+ # on the start and/or the end of the corresponding time interval within the
92
+ # specific "calendar year".
92
93
  class Years < ISO8601::Atom
93
94
  ##
94
95
  # The Year factor
95
96
  #
96
- # The duration year average is calculated through time intervals of 400
97
- # duration years”. Each cycle of 400 duration years has 303 common
98
- # years of 365 calendar days and 97 leap years of 366 calendar days”.
97
+ # The "duration year" average is calculated through time intervals of 400
98
+ # "duration years". Each cycle of 400 "duration years" has 303 "common
99
+ # years" of 365 "calendar days" and 97 "leap years" of 366 "calendar days".
99
100
  #
100
101
  # @return [Integer]
101
102
  def factor
@@ -120,19 +121,19 @@ module ISO8601
120
121
  ##
121
122
  # A Months atom in a {ISO8601::Duration}
122
123
  #
123
- # A calendar month is the time interval resulting from the division of a
124
- # calendar year in 12 time intervals.
124
+ # A "calendar month" is the time interval resulting from the division of a
125
+ # "calendar year" in 12 time intervals.
125
126
  #
126
- # A duration month is the duration of 28, 29, 30 or 31 calendar days
127
+ # A "duration month" is the duration of 28, 29, 30 or 31 "calendar days"
127
128
  # depending on the start and/or the end of the corresponding time interval
128
- # within the specific calendar month”.
129
+ # within the specific "calendar month".
129
130
  class Months < ISO8601::Atom
130
131
  ##
131
132
  # The Month factor
132
133
  #
133
- # The duration month average is calculated through time intervals of 400
134
- # duration years”. Each cycle of 400 duration years has 303 common
135
- # years of 365 calendar days and 97 leap years of 366 calendar days”.
134
+ # The "duration month" average is calculated through time intervals of 400
135
+ # "duration years". Each cycle of 400 "duration years" has 303 "common
136
+ # years" of 365 "calendar days" and 97 "leap years" of 366 "calendar days".
136
137
  def factor
137
138
  if base.nil?
138
139
  nobase_calculation
@@ -157,25 +158,26 @@ module ISO8601
157
158
  end
158
159
 
159
160
  def zero_calculation
160
- month = (base.month <= 12) ? (base.month) : ((base.month) % 12)
161
+ month = (base.month <= 12) ? base.month : (base.month % 12)
161
162
  year = base.year + ((base.month) / 12).to_i
162
163
 
163
164
  (::Time.utc(year, month) - ::Time.utc(base.year, base.month))
164
165
  end
165
166
 
166
167
  def calculation
167
- if base.month + atom <= 0
168
+ initial = base.month + atom
169
+ if initial <= 0
168
170
  month = base.month + atom
169
171
 
170
- if month % 12 == 0
171
- year = base.year + (month / 12) - 1
172
+ if initial % 12 == 0
173
+ year = base.year + (initial / 12) - 1
172
174
  month = 12
173
175
  else
174
- year = base.year + (month / 12).floor
175
- month = (12 + month > 0) ? (12 + month) : (12 + (month % -12))
176
+ year = base.year + (initial / 12).floor
177
+ month = (12 + initial > 0) ? (12 + initial) : (12 + (initial % -12))
176
178
  end
177
179
  else
178
- month = (base.month + atom <= 12) ? (base.month + atom) : ((base.month + atom) % 12)
180
+ month = (initial <= 12) ? initial : (initial % 12)
179
181
  month = 12 if month.zero?
180
182
  year = base.year + ((base.month + atom) / 12).to_i
181
183
  end
@@ -202,9 +204,9 @@ module ISO8601
202
204
  ##
203
205
  # The Days atom in a {ISO8601::Duration}
204
206
  #
205
- # A calendar day is the time interval which starts at a certain time of day
206
- # at a certain calendar day and ends at the same time of day at the next
207
- # calendar day”.
207
+ # A "calendar day" is the time interval which starts at a certain time of day
208
+ # at a certain "calendar day" and ends at the same time of day at the next
209
+ # "calendar day".
208
210
  class Days < ISO8601::Atom
209
211
  ##
210
212
  # The Day factor
@@ -256,7 +258,7 @@ module ISO8601
256
258
  #
257
259
  # The second is the base unit of measurement of time in the International
258
260
  # System of Units (SI) as defined by the International Committee of Weights
259
- # and Measures (CIPM, i.e. Comité International des Poids et Mesures)
261
+ # and Measures.
260
262
  class Seconds < ISO8601::Atom
261
263
  ##
262
264
  # The Second factor
@@ -15,9 +15,11 @@ module ISO8601
15
15
  class Date
16
16
  extend Forwardable
17
17
 
18
- def_delegators(:@date,
18
+ def_delegators(
19
+ :@date,
19
20
  :to_s, :to_time, :to_date, :to_datetime,
20
- :year, :month, :day, :wday)
21
+ :year, :month, :day, :wday
22
+ )
21
23
  ##
22
24
  # The original atoms
23
25
  attr_reader :atoms
@@ -41,20 +43,20 @@ module ISO8601
41
43
  ##
42
44
  # Forwards the date the given amount of days.
43
45
  #
44
- # @param [Numeric] days The days to add
46
+ # @param [Numeric] other The days to add
45
47
  #
46
48
  # @return [ISO8601::Date] New date resulting of the addition
47
- def +(days)
48
- ISO8601::Date.new((@date + days).iso8601)
49
+ def +(other)
50
+ ISO8601::Date.new((@date + other).iso8601)
49
51
  end
50
52
  ##
51
53
  # Backwards the date the given amount of days.
52
54
  #
53
- # @param [Numeric] days The days to remove
55
+ # @param [Numeric] other The days to remove
54
56
  #
55
57
  # @return [ISO8601::Date] New date resulting of the substraction
56
- def -(days)
57
- ISO8601::Date.new((@date - days).iso8601)
58
+ def -(other)
59
+ ISO8601::Date.new((@date - other).iso8601)
58
60
  end
59
61
  ##
60
62
  # Converts self to an array of atoms.
@@ -62,18 +64,18 @@ module ISO8601
62
64
  [year, month, day]
63
65
  end
64
66
  ##
65
- # @param [#hash] contrast The contrast to compare against
67
+ # @param [#hash] other The contrast to compare against
66
68
  #
67
69
  # @return [Boolean]
68
- def ==(contrast)
69
- (hash == contrast.hash)
70
+ def ==(other)
71
+ (hash == other.hash)
70
72
  end
71
73
  ##
72
- # @param [#hash] contrast The contrast to compare against
74
+ # @param [#hash] other The contrast to compare against
73
75
  #
74
76
  # @return [Boolean]
75
- def eql?(contrast)
76
- (hash == contrast.hash)
77
+ def eql?(other)
78
+ (hash == other.hash)
77
79
  end
78
80
  ##
79
81
  # @return [Fixnum]
@@ -82,6 +84,7 @@ module ISO8601
82
84
  end
83
85
 
84
86
  private
87
+
85
88
  ##
86
89
  # Splits the date component into valid atoms.
87
90
  #
@@ -101,7 +104,8 @@ module ISO8601
101
104
  week_date = /^([+-]?)\d{4}(-?)W\d{2}(?:\2\d)?$/.match(input)
102
105
  return atomize_week_date(input, week_date[2], week_date[1]) unless week_date.nil?
103
106
 
104
- _, sign, year, separator, day = /^([+-]?)(\d{4})(-?)(\d{3})$/.match(input).to_a.compact
107
+ ordinal_regexp = /^([+-]?)(\d{4})(-?)(\d{3})$/
108
+ _, sign, year, separator, day = ordinal_regexp.match(input).to_a.compact
105
109
  return atomize_ordinal(year, day, separator, sign) unless year.nil?
106
110
 
107
111
  _, year, separator, month, day = /^
@@ -114,7 +118,7 @@ module ISO8601
114
118
  )?
115
119
  $/x.match(input).to_a.compact
116
120
 
117
- raise ISO8601::Errors::UnknownPattern.new(@original) if year.nil?
121
+ fail ISO8601::Errors::UnknownPattern, @original if year.nil?
118
122
 
119
123
  @separator = separator
120
124
 
@@ -10,9 +10,11 @@ module ISO8601
10
10
  class DateTime
11
11
  extend Forwardable
12
12
 
13
- def_delegators(:@date_time,
13
+ def_delegators(
14
+ :@date_time,
14
15
  :strftime, :to_time, :to_date, :to_datetime,
15
- :year, :month, :day, :hour, :minute, :zone)
16
+ :year, :month, :day, :hour, :minute, :zone
17
+ )
16
18
 
17
19
  attr_reader :second
18
20
 
@@ -29,9 +31,9 @@ module ISO8601
29
31
  ##
30
32
  # Addition
31
33
  #
32
- # @param [Numeric] seconds The seconds to add
33
- def +(seconds)
34
- moment = @date_time.to_time.localtime(zone) + seconds
34
+ # @param [Numeric] other The seconds to add
35
+ def +(other)
36
+ moment = @date_time.to_time.localtime(zone) + other
35
37
  format = moment.subsec.zero? ? FORMAT : FORMAT_WITH_FRACTION
36
38
 
37
39
  ISO8601::DateTime.new(moment.strftime(format))
@@ -39,9 +41,9 @@ module ISO8601
39
41
  ##
40
42
  # Substraction
41
43
  #
42
- # @param [Numeric] seconds The seconds to substract
43
- def -(seconds)
44
- moment = @date_time.to_time.localtime(zone) - seconds
44
+ # @param [Numeric] other The seconds to substract
45
+ def -(other)
46
+ moment = @date_time.to_time.localtime(zone) - other
45
47
  format = moment.subsec.zero? ? FORMAT : FORMAT_WITH_FRACTION
46
48
 
47
49
  ISO8601::DateTime.new(moment.strftime(format))
@@ -58,18 +60,18 @@ module ISO8601
58
60
  [year, month, day, hour, minute, second, zone]
59
61
  end
60
62
  ##
61
- # @param [#hash] contrast The contrast to compare against
63
+ # @param [#hash] other The contrast to compare against
62
64
  #
63
65
  # @return [Boolean]
64
- def ==(contrast)
65
- (hash == contrast.hash)
66
+ def ==(other)
67
+ (hash == other.hash)
66
68
  end
67
69
  ##
68
- # @param [#hash] contrast The contrast to compare against
70
+ # @param [#hash] other The contrast to compare against
69
71
  #
70
72
  # @return [Boolean]
71
- def eql?(contrast)
72
- (hash == contrast.hash)
73
+ def eql?(other)
74
+ (hash == other.hash)
73
75
  end
74
76
  ##
75
77
  # @return [Fixnum]
@@ -77,8 +79,8 @@ module ISO8601
77
79
  [second, self.class].hash
78
80
  end
79
81
 
80
-
81
82
  private
83
+
82
84
  ##
83
85
  # Parses an ISO date time, where the date and the time components are
84
86
  # optional.
@@ -87,20 +89,20 @@ module ISO8601
87
89
  #
88
90
  # @param [String] date_time The ISO representation
89
91
  def parse(date_time)
90
- raise ISO8601::Errors::UnknownPattern, date_time if date_time.empty?
92
+ fail ISO8601::Errors::UnknownPattern, date_time if date_time.empty?
91
93
 
92
94
  date, time = date_time.split('T')
93
95
 
94
- date_components = parse_date(date)
95
- time_components = Array(time && parse_time(time))
96
- separators = [date_components.pop, time_components.pop]
96
+ date_atoms = parse_date(date)
97
+ time_atoms = Array(time && parse_time(time))
98
+ separators = [date_atoms.pop, time_atoms.pop]
97
99
 
98
- raise ISO8601::Errors::UnknownPattern, @original unless valid_representation?(date_components, time_components)
99
- raise ISO8601::Errors::UnknownPattern, @original unless valid_separators?(separators)
100
+ fail ISO8601::Errors::UnknownPattern,
101
+ @original unless valid_representation?(date_atoms, time_atoms)
102
+ fail ISO8601::Errors::UnknownPattern,
103
+ @original unless valid_separators?(separators)
100
104
 
101
- components = date_components + time_components
102
-
103
- ::DateTime.new(*components.compact)
105
+ ::DateTime.new(*(date_atoms + time_atoms).compact)
104
106
  end
105
107
  ##
106
108
  # Validates the date has the right pattern.
@@ -134,13 +136,14 @@ module ISO8601
134
136
  unless separators.all?(&:empty?)
135
137
  return false if (separators.first.length != separators.last.length)
136
138
  end
137
- return true
139
+
140
+ true
138
141
  end
139
142
  ##
140
143
  # If time is provided date must use a complete representation
141
144
  def valid_representation?(date, time)
142
145
  year, month, day = date
143
- hour, minute, second = time
146
+ hour, _ = time
144
147
 
145
148
  date.nil? || !(!year.nil? && (month.nil? || day.nil?) && !hour.nil?)
146
149
  end
@@ -3,7 +3,8 @@
3
3
  module ISO8601
4
4
  ##
5
5
  # A duration representation. When no base is provided, all atoms use an
6
- # average factor which affects the result of any computation like `#to_seconds`.
6
+ # average factor which affects the result of any computation like
7
+ # `#to_seconds`.
7
8
  #
8
9
  # @example
9
10
  # d = ISO8601::Duration.new('P2Y1MT2H')
@@ -14,11 +15,16 @@ module ISO8601
14
15
  # d.to_seconds # => 65707200.0
15
16
  #
16
17
  # @example Explicit base date time
17
- # d = ISO8601::Duration.new('P2Y1MT2H', ISO8601::DateTime.new('2014-08017'))
18
- # d.years # => #<ISO8601::Years:0x000000051adee8 @atom=2.0, @base=#<ISO8601::DateTime...>>
19
- # d.months # => #<ISO8601::Months:0x00000004f230b0 @atom=1.0, @base=#<ISO8601::DateTime...>>
20
- # d.days # => #<ISO8601::Days:0x00000005205468 @atom=0, @base=#<ISO8601::DateTime...>>
21
- # d.hours # => #<ISO8601::Hours:0x000000051e02a8 @atom=2.0, @base=#<ISO8601::DateTime...>>
18
+ # base = ISO8601::DateTime.new('2014-08017')
19
+ # d = ISO8601::Duration.new('P2Y1MT2H', base)
20
+ # d.years # => #<ISO8601::Years:0x000000051adee8 @atom=2.0,
21
+ # @base=#<ISO8601::DateTime...>>
22
+ # d.months # => #<ISO8601::Months:0x00000004f230b0 @atom=1.0,
23
+ # @base=#<ISO8601::DateTime...>>
24
+ # d.days # => #<ISO8601::Days:0x00000005205468 @atom=0,
25
+ # @base=#<ISO8601::DateTime...>>
26
+ # d.hours # => #<ISO8601::Hours:0x000000051e02a8 @atom=2.0,
27
+ # @base=#<ISO8601::DateTime...>>
22
28
  # d.to_seconds # => 65757600.0
23
29
  #
24
30
  # @example Number of seconds versus patterns
@@ -111,49 +117,40 @@ module ISO8601
111
117
  ##
112
118
  # Addition
113
119
  #
114
- # @param [ISO8601::Duration] duration The duration to add
120
+ # @param [ISO8601::Duration] other The duration to add
115
121
  #
116
122
  # @raise [ISO8601::Errors::DurationBaseError] If bases doesn't match
117
123
  # @return [ISO8601::Duration]
118
- def +(duration)
119
- compare_bases(duration)
120
-
121
- d1 = to_seconds
122
- d2 = duration.to_seconds
123
-
124
- seconds_to_iso(d1 + d2)
124
+ def +(other)
125
+ compare_bases(other)
126
+ seconds_to_iso(to_seconds + other.to_seconds)
125
127
  end
126
128
  ##
127
129
  # Substraction
128
130
  #
129
- # @param [ISO8601::Duration] duration The duration to substract
131
+ # @param [ISO8601::Duration] other The duration to substract
130
132
  #
131
133
  # @raise [ISO8601::Errors::DurationBaseError] If bases doesn't match
132
134
  # @return [ISO8601::Duration]
133
- def -(duration)
134
- compare_bases(duration)
135
-
136
- d1 = to_seconds
137
- d2 = duration.to_seconds
138
-
139
- seconds_to_iso(d1 - d2)
135
+ def -(other)
136
+ compare_bases(other)
137
+ seconds_to_iso(to_seconds - other.to_seconds)
140
138
  end
141
139
  ##
142
- # @param [ISO8601::Duration] duration The duration to compare
140
+ # @param [ISO8601::Duration] other The duration to compare
143
141
  #
144
142
  # @raise [ISO8601::Errors::DurationBaseError] If bases doesn't match
145
143
  # @return [Boolean]
146
- def ==(duration)
147
- compare_bases(duration)
148
-
149
- (to_seconds == duration.to_seconds)
144
+ def ==(other)
145
+ compare_bases(other)
146
+ (to_seconds == other.to_seconds)
150
147
  end
151
148
  ##
152
- # @param [ISO8601::Duration] duration The duration to compare
149
+ # @param [ISO8601::Duration] other The duration to compare
153
150
  #
154
151
  # @return [Boolean]
155
- def eql?(duration)
156
- (hash == duration.hash)
152
+ def eql?(other)
153
+ (hash == other.hash)
157
154
  end
158
155
  ##
159
156
  # @return [Fixnum]
@@ -165,16 +162,17 @@ module ISO8601
165
162
  #
166
163
  # @return [String]
167
164
  def to_pattern
168
- (@original.kind_of? Numeric) ? "PT#{@original}S" : @original
165
+ (@original.is_a? Numeric) ? "PT#{@original}S" : @original
169
166
  end
170
167
  ##
171
168
  # @return [Numeric] The duration in seconds
172
169
  def to_seconds
173
- [years, months, weeks, days, hours, minutes, seconds].map(&:to_seconds).reduce(&:+)
170
+ atoms = [years, months, weeks, days, hours, minutes, seconds]
171
+ atoms.map(&:to_seconds).reduce(&:+)
174
172
  end
175
173
 
176
-
177
174
  private
175
+
178
176
  ##
179
177
  # Splits a duration pattern into valid atoms.
180
178
  #
@@ -207,15 +205,17 @@ module ISO8601
207
205
  ) |
208
206
  (?<weeks>\d+(?:[.,]\d+)?W)
209
207
  ) # Duration
210
- $/x) or raise ISO8601::Errors::UnknownPattern.new(input)
208
+ $/x) || fail(ISO8601::Errors::UnknownPattern, input)
211
209
 
212
210
  valid_pattern?(duration)
213
211
 
214
- @sign = (duration[:sign].nil? || duration[:sign] == '+') ? 1 : -1
212
+ @sign = (duration[:sign] == '-') ? -1 : 1
215
213
 
216
- keys = duration.names.map(&:to_sym)
217
- values = duration.captures.map { |v| v.to_f * sign }
218
- components = Hash[keys.zip(values)]
214
+ components = duration.names.zip(duration.captures).map! do |k, v|
215
+ value = v.nil? ? v : v.tr(',', '.')
216
+ [k.to_sym, sign * value.to_f]
217
+ end
218
+ components = Hash[components]
219
219
  components.delete(:time) # clean time capture
220
220
 
221
221
  valid_fractions?(components.values)
@@ -258,31 +258,36 @@ module ISO8601
258
258
  end
259
259
 
260
260
  def validate_base(input)
261
- raise ISO8601::Errors::TypeError if !(input.nil? or input.kind_of? ISO8601::DateTime)
261
+ fail ISO8601::Errors::TypeError unless input.nil? || input.is_a?(ISO8601::DateTime)
262
262
 
263
263
  input
264
264
  end
265
+
265
266
  def valid_pattern?(components)
266
- date = [components[:years], components[:months], components[:days]].compact
267
- time = [components[:hours], components[:minutes], components[:seconds]].compact
267
+ date = [
268
+ components[:years], components[:months], components[:days]
269
+ ]
270
+ time = [
271
+ components[:hours], components[:minutes], components[:seconds]
272
+ ].compact
268
273
  weeks = components[:weeks]
269
274
  all = [date, time, weeks].flatten.compact
270
275
 
271
- if all.empty? || (!components[:time].nil? && time.empty? && weeks.nil?)
272
- raise ISO8601::Errors::UnknownPattern.new(@pattern)
273
- end
276
+ missing_time = (weeks.nil? && !components[:time].nil? && time.empty?)
277
+ empty = missing_time || all.empty?
278
+ fail ISO8601::Errors::UnknownPattern, @pattern if empty
274
279
  end
275
280
 
276
281
  def valid_fractions?(values)
277
282
  values = values.reject(&:zero?)
278
283
  fractions = values.select { |a| (a % 1) != 0 }
279
- if fractions.size > 1 || (fractions.size == 1 && fractions.last != values.last)
280
- raise ISO8601::Errors::InvalidFractions.new(@pattern)
281
- end
284
+ consistent = (fractions.size == 1 && fractions.last != values.last)
285
+
286
+ fail ISO8601::Errors::InvalidFractions if fractions.size > 1 || consistent
282
287
  end
283
288
 
284
- def compare_bases(duration)
285
- raise ISO8601::Errors::DurationBaseError.new(duration) if base.to_s != duration.base.to_s
289
+ def compare_bases(other)
290
+ fail ISO8601::Errors::DurationBaseError, other if base != other.base
286
291
  end
287
292
  end
288
293
  end
@@ -1,23 +1,20 @@
1
- # encoding: utf-8
2
-
3
1
  module ISO8601
4
2
  ##
5
3
  # Contains all ISO8601-specific errors.
6
4
  module Errors
7
-
8
5
  class StandardError < ::StandardError
9
6
  end
10
7
  ##
11
8
  # Raised when the given pattern doesn't fit as ISO 8601 parser.
12
9
  class UnknownPattern < StandardError
13
10
  def initialize(pattern)
14
- super("The pattern “#{pattern}” is not allowed in this implementation of ISO8601.")
11
+ super("Unknown pattern #{pattern}")
15
12
  end
16
13
  end
17
14
  ##
18
15
  # Raised when the given pattern contains an invalid fraction.
19
16
  class InvalidFractions < StandardError
20
- def initialize(pattern)
17
+ def initialize
21
18
  super("Fractions are only allowed in the last component")
22
19
  end
23
20
  end
@@ -25,7 +22,7 @@ module ISO8601
25
22
  # Raised when the given date is valid but out of range.
26
23
  class RangeError < StandardError
27
24
  def initialize(pattern)
28
- super("“#{pattern} is out of range")
25
+ super("#{pattern} is out of range")
29
26
  end
30
27
  end
31
28
  ##
@@ -12,9 +12,11 @@ module ISO8601
12
12
  class Time
13
13
  extend Forwardable
14
14
 
15
- def_delegators(:@time,
15
+ def_delegators(
16
+ :@time,
16
17
  :to_time, :to_date, :to_datetime,
17
- :hour, :minute, :zone)
18
+ :hour, :minute, :zone
19
+ )
18
20
  ##
19
21
  # The separator used in the original ISO 8601 string.
20
22
  attr_reader :separator
@@ -39,18 +41,18 @@ module ISO8601
39
41
  @second = @time.second + @time.second_fraction.to_f
40
42
  end
41
43
  ##
42
- # @param [#hash] contrast The contrast to compare against
44
+ # @param [#hash] other The contrast to compare against
43
45
  #
44
46
  # @return [Boolean]
45
- def ==(contrast)
46
- (hash == contrast.hash)
47
+ def ==(other)
48
+ (hash == other.hash)
47
49
  end
48
50
  ##
49
- # @param [#hash] contrast The contrast to compare against
51
+ # @param [#hash] other The contrast to compare against
50
52
  #
51
53
  # @return [Boolean]
52
- def eql?(contrast)
53
- (hash == contrast.hash)
54
+ def eql?(other)
55
+ (hash == other.hash)
54
56
  end
55
57
  ##
56
58
  # @return [Fixnum]
@@ -60,26 +62,28 @@ module ISO8601
60
62
  ##
61
63
  # Forwards the time the given amount of seconds.
62
64
  #
63
- # @param [Numeric] seconds The seconds to add
65
+ # @param [Numeric] other The seconds to add
64
66
  #
65
67
  # @return [ISO8601::Time] New time resulting of the addition
66
- def +(seconds)
67
- moment = @time.to_time.localtime(zone) + seconds
68
+ def +(other)
69
+ moment = @time.to_time.localtime(zone) + other
68
70
  format = moment.subsec.zero? ? FORMAT : FORMAT_WITH_FRACTION
71
+ base = ::Date.parse(moment.strftime('%Y-%m-%d'))
69
72
 
70
- ISO8601::Time.new(moment.strftime(format), ::Date.parse(moment.strftime('%Y-%m-%d')))
73
+ ISO8601::Time.new(moment.strftime(format), base)
71
74
  end
72
75
  ##
73
76
  # Backwards the date the given amount of seconds.
74
77
  #
75
- # @param [Numeric] seconds The seconds to remove
78
+ # @param [Numeric] other The seconds to remove
76
79
  #
77
80
  # @return [ISO8601::Time] New time resulting of the substraction
78
- def -(seconds)
79
- moment = @time.to_time.localtime(zone) - seconds
81
+ def -(other)
82
+ moment = @time.to_time.localtime(zone) - other
80
83
  format = moment.subsec.zero? ? FORMAT : FORMAT_WITH_FRACTION
84
+ base = ::Date.parse(moment.strftime('%Y-%m-%d'))
81
85
 
82
- ISO8601::Time.new(moment.strftime(format), ::Date.parse(moment.strftime('%Y-%m-%d')))
86
+ ISO8601::Time.new(moment.strftime(format), base)
83
87
  end
84
88
  ##
85
89
  # Converts self to a time component representation.
@@ -94,6 +98,7 @@ module ISO8601
94
98
  end
95
99
 
96
100
  private
101
+
97
102
  ##
98
103
  # Splits the time component into valid atoms.
99
104
  # Acceptable patterns: hh, hh:mm or hhmm and hh:mm:ss or hhmmss. Any form
@@ -111,7 +116,7 @@ module ISO8601
111
116
  (\d{2})
112
117
  )$/x.match(time).to_a.compact
113
118
 
114
- raise ISO8601::Errors::UnknownPattern.new(@original) if hour.nil?
119
+ fail ISO8601::Errors::UnknownPattern, @original if hour.nil?
115
120
 
116
121
  @separator = separator
117
122
 
@@ -119,13 +124,14 @@ module ISO8601
119
124
  minute &&= minute.to_i
120
125
  second &&= second.to_f
121
126
 
122
- raise ISO8601::Errors::UnknownPattern.new(@original) unless valid_zone?(zone)
127
+ fail ISO8601::Errors::UnknownPattern, @original unless valid_zone?(zone)
123
128
 
124
129
  [hour, minute, second, zone].compact
125
130
  end
126
131
 
127
132
  def valid_zone?(zone)
128
- _, offset, separator = /^(Z|[+-]\d{2}(?:(:?)\d{2})?)$/.match(zone).to_a.compact
133
+ zone_regexp = /^(Z|[+-]\d{2}(?:(:?)\d{2})?)$/
134
+ _, offset, separator = zone_regexp.match(zone).to_a.compact
129
135
 
130
136
  wrong_pattern = !zone.nil? && offset.nil?
131
137
  invalid_separators = zone.to_s.match(/^[+-]\d{2}:?\d{2}$/) && (@separator != separator)
@@ -1,5 +1,5 @@
1
1
  module ISO8601
2
2
  ##
3
3
  # The gem version
4
- VERSION = '0.8.0'
4
+ VERSION = '0.8.1'
5
5
  end
@@ -221,6 +221,7 @@ RSpec.describe ISO8601::Duration do
221
221
  it "should return the seconds of a -PT[n]H[n]M duration" do
222
222
  expect(ISO8601::Duration.new('-PT10S', ISO8601::DateTime.new('2012-01-01T00:00:00')).to_seconds).to eq(Time.utc(2011, 12, 31, 23, 59, 50) - Time.utc(2012, 1))
223
223
  expect(ISO8601::Duration.new('-PT10.4S', ISO8601::DateTime.new('2012-01-01')).to_seconds).to eq(-10.4)
224
+ expect(ISO8601::Duration.new('-PT10,4S', ISO8601::DateTime.new('2012-01-01')).to_seconds).to eq(-10.4)
224
225
  end
225
226
  end
226
227
  end
@@ -250,7 +251,7 @@ RSpec.describe ISO8601::Duration do
250
251
  expect(subject).to respond_to(:eql?)
251
252
  end
252
253
  it "should equal by hash identity" do
253
- expect(ISO8601::Duration.new('PT1H').eql? ISO8601::Duration.new('PT1H')).to be_truthy
254
+ expect(ISO8601::Duration.new('PT1H').eql? ISO8601::Duration.new('PT1H')).to be_truthy
254
255
  expect(ISO8601::Duration.new('PT1H').eql? ISO8601::Duration.new('PT60M')).to be_falsy
255
256
  end
256
257
 
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- $:.unshift File.expand_path('..', __FILE__)
3
+ $LOAD_PATH.unshift File.expand_path('..', __FILE__)
4
4
  require 'iso8601'
5
5
 
6
6
  RSpec.configure do |config|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iso8601
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arnau Siches
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-06 00:00:00.000000000 Z
11
+ date: 2014-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -25,28 +25,30 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.1'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rerun
28
+ name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '0.26'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
41
- description: " ISO8601 is a simple implementation in Ruby of the ISO 8601 (Data
42
- elements and \n interchange formats - Information interchange - Representation
43
- of dates \n and times) standard.\n"
40
+ version: '0.26'
41
+ description: |2
42
+ ISO8601 is a simple implementation in Ruby of the ISO 8601 (Data elements and
43
+ interchange formats - Information interchange - Representation of dates
44
+ and times) standard.
44
45
  email: arnau.siches@gmail.com
45
46
  executables: []
46
47
  extensions: []
47
48
  extra_rdoc_files: []
48
49
  files:
49
50
  - ".gitignore"
51
+ - ".rubocop.yml"
50
52
  - ".travis.yml"
51
53
  - CHANGELOG.md
52
54
  - Gemfile
@@ -80,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
82
  requirements:
81
83
  - - ">="
82
84
  - !ruby/object:Gem::Version
83
- version: '0'
85
+ version: 1.9.3
84
86
  required_rubygems_version: !ruby/object:Gem::Requirement
85
87
  requirements:
86
88
  - - ">="