diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs index a6c3aa4e9983fc..a0ab14caadabeb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs @@ -5171,7 +5171,9 @@ private static bool TryParseFormatO(ReadOnlySpan source, scoped ref DateTi second = (int)(s1 * 10 + s2); } - double fraction; + // The seven fractional digits are sub-second ticks (1 tick = 100 ns = 10^-7 s), + // matching TimeSpan.TicksPerSecond, so we can use them directly without floating-point math. + int fractionTicks; { uint f1 = (uint)(source[20] - '0'); uint f2 = (uint)(source[21] - '0'); @@ -5187,12 +5189,12 @@ private static bool TryParseFormatO(ReadOnlySpan source, scoped ref DateTi return false; } - fraction = (f1 * 1000000 + f2 * 100000 + f3 * 10000 + f4 * 1000 + f5 * 100 + f6 * 10 + f7) / 10000000.0; + fractionTicks = (int)(f1 * 1000000 + f2 * 100000 + f3 * 10000 + f4 * 1000 + f5 * 100 + f6 * 10 + f7); } // Per ISO 8601, 24:00:00 represents the end of a calendar day // (the same instant as the next day's 00:00:00), but only when minute, second, and fraction are all zero - if (hour == 24 && (minute != 0 || second != 0 || fraction != 0)) + if (hour == 24 && (minute != 0 || second != 0 || fractionTicks != 0)) { result.SetBadDateTimeFailure(); return false; @@ -5204,7 +5206,7 @@ private static bool TryParseFormatO(ReadOnlySpan source, scoped ref DateTi return false; } - if (!dateTime.TryAddTicks((long)Math.Round(fraction * TimeSpan.TicksPerSecond), out result.parsedDate)) + if (!dateTime.TryAddTicks(fractionTicks, out result.parsedDate)) { result.SetBadDateTimeFailure(); return false;