org.sonar.plugins.csharp.S6561.html Maven / Gradle / Ivy
The rule targets the use of DateTime.Now
call followed by some arithmetic operation.
Why is this an issue?
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).
How to fix it
Code examples
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
.
Noncompliant code example
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
Compliant solution
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.
Noncompliant code example
if ((DateTime.Now - lastRefresh).TotalMilliseconds > MinRefreshInterval)
{
lastRefresh = DateTime.Now;
// Refresh
}
Compliant solution
if ((DateTime.UtcNow - lastRefresh).TotalMilliseconds > MinRefreshInterval)
{
lastRefresh = DateTime.UtcNow;
// Refresh
}
Resources
Documentation