The rule targets the use of DateTime.Now call followed by some arithmetic operation.
Using DateTime.Now calls within a subtraction operation to measure elapsed time is not recommended. This property is subject to
changes such as daylight savings transitions, which can invalidate the calculation if the change occurs during the benchmark session, or when updating
a timer. Moreover, DateTime.Now is dependent on the system clock, which may have low resolution on older systems (as low as 15
milliseconds).
If the purpose is to benchmark something then, instead of the DateTime.Now property, it’s recommended to use Stopwatch,
which is not affected by changes in time such as daylight savings (DST) and automatically checks for the existence of high-precision timers. As a
bonus, the StopWatch class is also lightweight and computationally faster than DateTime.
var start = DateTime.Now; // First call, on March 26th 2:59 am
MethodToBeBenchmarked();
Console.WriteLine($"{(DateTime.Now - start).TotalMilliseconds} ms"); // Second call happens 2 minutes later but `Now` is March 26th, 4:01 am as there's a shift to summer time
var stopWatch = Stopwatch.StartNew(); // Compliant
MethodToBeBenchmarked();
stopWatch.Stop();
Console.WriteLine($"{stopWatch.ElapsedMilliseconds} ms");
If, on the other hand, the goal is to refresh a timer prefer using the DateTime.UtcNow property, which guarantees reliable results
when doing arithmetic operations during DST transitions.
if ((DateTime.Now - lastRefresh).TotalMilliseconds > MinRefreshInterval)
{
lastRefresh = DateTime.Now;
// Refresh
}
if ((DateTime.UtcNow - lastRefresh).TotalMilliseconds > MinRefreshInterval)
{
lastRefresh = DateTime.UtcNow;
// Refresh
}