1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Always use %f formatter for ISO8601 durations since they can't be in scientific notation

Manually formats the seconds. This avoids using the %g formatter which can convert large numbers or very small fractions into scientific notation which is not supported by iso8601
This commit is contained in:
Adam Hess 2021-06-01 10:16:46 -07:00
parent ee8134d6f9
commit 6489ee522a
2 changed files with 10 additions and 1 deletions

View file

@ -27,7 +27,7 @@ module ActiveSupport
time << "#{parts[:hours]}H" if parts.key?(:hours) time << "#{parts[:hours]}H" if parts.key?(:hours)
time << "#{parts[:minutes]}M" if parts.key?(:minutes) time << "#{parts[:minutes]}M" if parts.key?(:minutes)
if parts.key?(:seconds) if parts.key?(:seconds)
time << "#{sprintf(@precision ? "%0.0#{@precision}f" : '%g', parts[:seconds])}S" time << "#{format_seconds(parts[:seconds])}S"
end end
output << "T#{time}" unless time.empty? output << "T#{time}" unless time.empty?
output output
@ -54,6 +54,14 @@ module ActiveSupport
def week_mixed_with_date?(parts) def week_mixed_with_date?(parts)
parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any? parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
end end
def format_seconds(seconds)
if @precision
sprintf("%0.0#{@precision}f", seconds)
else
seconds.to_s
end
end
end end
end end
end end

View file

@ -625,6 +625,7 @@ class DurationTest < ActiveSupport::TestCase
["P1Y1M1DT1H", 1.year + 1.month + 1.day + 1.hour], ["P1Y1M1DT1H", 1.year + 1.month + 1.day + 1.hour],
["PT0S", 0.minutes ], ["PT0S", 0.minutes ],
["PT-0.2S", (-0.2).seconds ], ["PT-0.2S", (-0.2).seconds ],
["PT1000000S", 1_000_000.seconds ],
] ]
expectations.each do |expected_output, duration| expectations.each do |expected_output, duration|
assert_equal expected_output, duration.iso8601, expected_output.inspect assert_equal expected_output, duration.iso8601, expected_output.inspect