Skip to content

Commit 86ec46a

Browse files
urmastalimaajosevalim
authored andcommitted
Fix parsing of fractional durations (#13832)
The parsing of fractional durations checked for non-negativity by testing second > 0, which reports false for not only negative integers but also for 0. Note that changing `if second > 0` to `if second >= 0` would fix behaviour for "PT0,6S", but would break "PT-0,6S".
1 parent c996318 commit 86ec46a

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

Diff for: lib/elixir/lib/calendar/iso.ex

+9-1
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,15 @@ defmodule Calendar.ISO do
715715
{second, <<delimiter, _::binary>> = rest} when delimiter in [?., ?,] ->
716716
case parse_microsecond(rest) do
717717
{{ms, precision}, "S"} ->
718-
ms = if second > 0, do: ms, else: -ms
718+
ms =
719+
case string do
720+
"-" <> _ ->
721+
-ms
722+
723+
_ ->
724+
ms
725+
end
726+
719727
{:ok, [second: second, microsecond: {ms, precision}] ++ acc}
720728

721729
_ ->

Diff for: lib/elixir/test/elixir/calendar/duration_test.exs

+5
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,10 @@ defmodule DurationTest do
237237
assert Duration.from_iso8601("P4Y2W3Y") == {:error, :invalid_date_component}
238238
assert Duration.from_iso8601("P5HT4MT3S") == {:error, :invalid_date_component}
239239
assert Duration.from_iso8601("P5H3HT4M") == {:error, :invalid_date_component}
240+
assert Duration.from_iso8601("P0.5Y") == {:error, :invalid_date_component}
240241
assert Duration.from_iso8601("PT1D") == {:error, :invalid_time_component}
241242
assert Duration.from_iso8601("PT.6S") == {:error, :invalid_time_component}
243+
assert Duration.from_iso8601("PT0.5H") == {:error, :invalid_time_component}
242244
assert Duration.from_iso8601("invalid") == {:error, :invalid_duration}
243245
end
244246

@@ -262,6 +264,9 @@ defmodule DurationTest do
262264
assert Duration.from_iso8601!("PT6S") == %Duration{second: 6}
263265
assert Duration.from_iso8601!("PT1,6S") == %Duration{second: 1, microsecond: {600_000, 1}}
264266
assert Duration.from_iso8601!("PT-1.6S") == %Duration{second: -1, microsecond: {-600_000, 1}}
267+
assert Duration.from_iso8601!("PT0,6S") == %Duration{second: 0, microsecond: {600_000, 1}}
268+
assert Duration.from_iso8601!("PT-0,6S") == %Duration{second: 0, microsecond: {-600_000, 1}}
269+
assert Duration.from_iso8601!("-PT-0,6S") == %Duration{second: 0, microsecond: {600_000, 1}}
265270
assert Duration.from_iso8601!("-P10DT4H") == %Duration{day: -10, hour: -4}
266271
assert Duration.from_iso8601!("-P10DT-4H") == %Duration{day: -10, hour: 4}
267272
assert Duration.from_iso8601!("P-10D") == %Duration{day: -10}

0 commit comments

Comments
 (0)