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 56

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. If all parts are negative it will negate all of them and return minus as a sign.

[ GitHub ]

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

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 52

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