Class: ISO8601::Duration

Inherits:
Object
  • Object
show all
Defined in:
lib/iso8601/duration.rb

Overview

TODO:

Support fraction values for years, months, days, weeks, hours and minutes

Represents a duration in ISO 8601 format

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pattern, base = nil) ⇒ Duration

Returns a new instance of Duration.

Parameters:

  • pattern (String, Numeric)

    The duration pattern

  • base (ISO8601::DateTime, nil) (defaults to: nil)

    (nil) The base datetime to calculate the duration properly



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/iso8601/duration.rb', line 15

def initialize(pattern, base = nil)
  # we got seconds instead of an ISO8601 duration
  pattern = "PT#{pattern}S" if (pattern.kind_of? Numeric)
  @duration = /^(\+|-)? # Sign
               P(
                  (
                    (\d+(?:[,.]\d+)?Y)? # Years
                    (\d+(?:[.,]\d+)?M)? # Months
                    (\d+(?:[.,]\d+)?D)? # Days
                    (T
                      (\d+(?:[.,]\d+)?H)? # Hours
                      (\d+(?:[.,]\d+)?M)? # Minutes
                      (\d+(?:[.,]\d+)?S)? # Seconds
                    )? # Time
                  )
                  |(\d+(?:[.,]\d+)?W) # Weeks
                ) # Duration
              $/x.match(pattern) or raise ISO8601::Errors::UnknownPattern.new(pattern)

  @base = base
  valid_pattern?
  valid_base?
  @atoms = {
    :years => @duration[4].nil? ? 0 : @duration[4].chop.to_f * sign,
    :months => @duration[5].nil? ? 0 : @duration[5].chop.to_f * sign,
    :weeks => @duration[11].nil? ? 0 : @duration[11].chop.to_f * sign,
    :days => @duration[6].nil? ? 0 : @duration[6].chop.to_f * sign,
    :hours => @duration[8].nil? ? 0 : @duration[8].chop.to_f * sign,
    :minutes => @duration[9].nil? ? 0 : @duration[9].chop.to_f * sign,
    :seconds => @duration[10].nil? ? 0 : @duration[10].chop.to_f * sign
  }
  valid_fractions?
end

Instance Attribute Details

#atomsObject (readonly)

Returns the value of attribute atoms.



10
11
12
# File 'lib/iso8601/duration.rb', line 10

def atoms
  @atoms
end

#baseObject

Returns the value of attribute base.



10
11
12
# File 'lib/iso8601/duration.rb', line 10

def base
  @base
end

Instance Method Details

#+(duration) ⇒ ISO8601::Duration

Addition

Parameters:

Returns:

Raises:



118
119
120
121
122
123
# File 'lib/iso8601/duration.rb', line 118

def +(duration)
  raise ISO8601::Errors::DurationBaseError.new(duration) if @base.to_s != duration.base.to_s
  d1 = to_seconds
  d2 = duration.to_seconds
  return seconds_to_iso(d1 + d2)
end

#-(duration) ⇒ ISO8601::Duration

Substraction

Parameters:

Returns:

Raises:



131
132
133
134
135
136
137
138
139
140
141
# File 'lib/iso8601/duration.rb', line 131

def -(duration)
  raise ISO8601::Errors::DurationBaseError.new(duration) if @base.to_s != duration.base.to_s
  d1 = to_seconds
  d2 = duration.to_seconds
  duration = d1 - d2
  if duration == 0
    return ISO8601::Duration.new('PT0S')
  else
    return seconds_to_iso(duration)
  end
end

#==(duration) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)

Raises:



147
148
149
150
# File 'lib/iso8601/duration.rb', line 147

def ==(duration)
  raise ISO8601::Errors::DurationBaseError.new(duration) if @base.to_s != duration.base.to_s
  (self.to_seconds == duration.to_seconds)
end

#absISO8601::Duration

Returns The absolute representation of the duration.

Returns:



107
108
109
110
# File 'lib/iso8601/duration.rb', line 107

def abs
  absolute = self.to_s.sub(/^[-+]/, '')
  return ISO8601::Duration.new(absolute)
end

#daysISO8601::Days

Returns The days of the duration.

Returns:



81
82
83
# File 'lib/iso8601/duration.rb', line 81

def days
  ISO8601::Days.new(@atoms[:days], @base)
end

#hashFixnum

Returns:

  • (Fixnum)


153
154
155
# File 'lib/iso8601/duration.rb', line 153

def hash
  @atoms.hash
end

#hoursISO8601::Hours

Returns The hours of the duration.

Returns:



86
87
88
# File 'lib/iso8601/duration.rb', line 86

def hours
  ISO8601::Hours.new(@atoms[:hours], @base)
end

#minutesISO8601::Minutes

Returns The minutes of the duration.

Returns:



91
92
93
# File 'lib/iso8601/duration.rb', line 91

def minutes
  ISO8601::Minutes.new(@atoms[:minutes], @base)
end

#monthsISO8601::Months

Returns The months of the duration.

Returns:



69
70
71
72
73
# File 'lib/iso8601/duration.rb', line 69

def months
  # Changes the base to compute the months for the right base year
  base = @base.nil? ? nil : @base + self.years.to_seconds
  ISO8601::Months.new(@atoms[:months], base)
end

#secondsISO8601::Seconds

Returns The seconds of the duration.

Returns:



96
97
98
# File 'lib/iso8601/duration.rb', line 96

def seconds
  ISO8601::Seconds.new(@atoms[:seconds], @base)
end

#to_sString

Returns The string representation of the duration.

Returns:

  • (String)

    The string representation of the duration



59
60
61
# File 'lib/iso8601/duration.rb', line 59

def to_s
  @duration[0]
end

#to_secondsNumeric

Returns The duration in seconds.

Returns:

  • (Numeric)

    The duration in seconds



101
102
103
104
# File 'lib/iso8601/duration.rb', line 101

def to_seconds
  years, months, weeks, days, hours, minutes, seconds = self.years.to_seconds, self.months.to_seconds, self.weeks.to_seconds, self.days.to_seconds, self.hours.to_seconds, self.minutes.to_seconds, self.seconds.to_seconds
  return years + months + weeks + days + hours + minutes + seconds
end

#weeksISO8601::Weeks

Returns The weeks of the duration.

Returns:



76
77
78
# File 'lib/iso8601/duration.rb', line 76

def weeks
  ISO8601::Weeks.new(@atoms[:weeks], @base)
end

#yearsISO8601::Years

Returns The years of the duration.

Returns:



64
65
66
# File 'lib/iso8601/duration.rb', line 64

def years
  ISO8601::Years.new(@atoms[:years], @base)
end