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
-
DATE_COMPONENTS =
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 10%i(years months days).freeze
Class Method Summary
Instance Method Summary
-
#serialize
Builds and returns output string.
-
#format_number(number)
private
Float#to_suses scientific notation for very small and very large values (e.g. - #format_seconds(seconds) private
-
#normalize
private
Return pair of duration's parts and whole duration sign.
- #week_mixed_with_date?(parts) ⇒ Boolean private
Constructor Details
.new(duration, precision: nil) ⇒ ISO8601Serializer
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 12
def initialize(duration, precision: nil) @duration = duration @precision = precision end
Instance Method Details
#format_number(number) (private)
Float#to_s uses scientific notation for very small and very large values
(e.g. "5.0e-05") and Rational#to_s writes a fraction ("3/2"), neither of
which is valid in ISO 8601.
#format_seconds(seconds) (private)
[ GitHub ]# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 58
def format_seconds(seconds) if @precision sprintf("%0.0#{@precision}f", seconds) else format_number(seconds) 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.
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 41
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.
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 18
def serialize parts = normalize return "PT0S" if parts.empty? output = +"P" output << "#{format_number(parts[:years])}Y" if parts.key?(:years) output << "#{format_number(parts[:months])}M" if parts.key?(:months) output << "#{format_number(parts[:days])}D" if parts.key?(:days) output << "#{format_number(parts[:weeks])}W" if parts.key?(:weeks) time = +"" time << "#{format_number(parts[:hours])}H" if parts.key?(:hours) time << "#{format_number(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)
# File 'activesupport/lib/active_support/duration/iso8601_serializer.rb', line 54
def week_mixed_with_date?(parts) parts.key?(:weeks) && parts.keys.intersect?(DATE_COMPONENTS) end