diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.cs index 63bbfc6b7d..1825a9fcd8 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlTypes/SqlTypeWorkarounds.cs @@ -61,23 +61,25 @@ internal static DateTime SqlDateTimeToDateTime(int daypart, int timepart) const int SQLTicksPerMinute = SQLTicksPerSecond * 60; const int SQLTicksPerHour = SQLTicksPerMinute * 60; const int SQLTicksPerDay = SQLTicksPerHour * 24; - const int MinDay = -53690; // Jan 1 1753 + //const int MinDay = -53690; // Jan 1 1753 + const uint MinDayOffset = 53690; // postive value of MinDay used to pull negative values up to 0 so a single check can be used const uint MaxDay = 2958463; // Dec 31 9999 is this many days from Jan 1 1900 const uint MaxTime = SQLTicksPerDay - 1; // = 25919999, 11:59:59:997PM - const int MinTime = 0; // 00:00:0:000PM const long BaseDateTicks = 599266080000000000L;//new DateTime(1900, 1, 1).Ticks; - if ((uint)daypart > MaxDay || (uint)timepart > MaxTime || daypart < MinDay || timepart < MinTime) + // casting to uint wraps negative values to large positive ones above the valid + // ranges so the lower bound doesn't need to be checked + if ((uint)(daypart + MinDayOffset) > (MaxDay + MinDayOffset) || (uint)timepart > MaxTime) { ThrowOverflowException(); } long dayticks = daypart * TimeSpan.TicksPerDay; double timePartPerMs = timepart / SQLTicksPerMillisecond; - double int1 = timePartPerMs + 0.5; - long timeticks1 = ((long)int1) * TimeSpan.TicksPerMillisecond; - long ticks1 = BaseDateTicks + dayticks + timeticks1; - return new DateTime(ticks1); + timePartPerMs += 0.5; + long timeTicks = ((long)timePartPerMs) * TimeSpan.TicksPerMillisecond; + long totalTicks = BaseDateTicks + dayticks + timeTicks; + return new DateTime(totalTicks); } private static void ThrowOverflowException()