iso8601 0.8.0 → 0.8.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.
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
  - - ">="