123456789_123456789_123456789_123456789_123456789_

Class: ActiveSupport::Duration::ISO8601Serializer

Do not use. This class is for internal use only.
Relationships & Source Files
Inherits: Object
Defined in: activesupport/lib/active_support/duration/iso8601_serializer.rb

Overview

Serializes duration to string according to ISO 8601 ::ActiveSupport::Duration format.

Constant Summary

Class Method Summary

Instance Method Summary

Constructor Details

.new(duration, precision: nil) ⇒ ISO8601Serializer

[ GitHub ]

  
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 9

def initialize(duration, precision: nil)
  @duration = duration
  @precision = precision
end

Instance Method Details

#format_seconds(seconds) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 55

def format_seconds(seconds)
  if @precision
    sprintf("%0.0#{@precision}f", seconds)
  else
    seconds.to_s
  end
end

#normalize (private)

Return pair of duration’s parts and whole duration sign. Parts are summarized (as they can become repetitive due to addition, etc). Zero parts are removed as not significant.

[ GitHub ]

  
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 38

def normalize
  parts = @duration.parts.each_with_object(Hash.new(0)) do |(k, v), p|
    p[k] += v  unless v.zero?
  end

  # Convert weeks to days and remove weeks if mixed with date parts
  if week_mixed_with_date?(parts)
    parts[:days] += parts.delete(:weeks) * SECONDS_PER_WEEK / SECONDS_PER_DAY
  end

  parts
end

#serialize

Builds and returns output string.

[ GitHub ]

  
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 15

def serialize
  parts = normalize
  return "PT0S" if parts.empty?

  output = +"P"
  output << "#{parts[:years]}Y"   if parts.key?(:years)
  output << "#{parts[:months]}M"  if parts.key?(:months)
  output << "#{parts[:days]}D"    if parts.key?(:days)
  output << "#{parts[:weeks]}W"   if parts.key?(:weeks)
  time = +""
  time << "#{parts[:hours]}H"     if parts.key?(:hours)
  time << "#{parts[:minutes]}M"   if parts.key?(:minutes)
  if parts.key?(:seconds)
    time << "#{format_seconds(parts[:seconds])}S"
  end
  output << "T#{time}" unless time.empty?
  output
end

#week_mixed_with_date?(parts) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 51

def week_mixed_with_date?(parts)
  parts.key?(:weeks) && parts.keys.intersect?(DATE_COMPONENTS)
end