org.sonar.plugins.csharp.S6563.html Maven / Gradle / Ivy
Why is this an issue?
You should avoid recording time instants with the use of property DateTime.Now
. The property DateTime.Now
returns the
current date and time expressed in the machine’s local time without containing any timezone-related information (for example, the offset from
Coordinated Universal Time). Not having this information means that if you need to display this DateTime
object or use it for
computations in another machine placed in a different time zone, you won’t be able to reconstruct it in the second machine’s local time without
knowing the origin’s offset. This will likely lead to confusion and potential bugs.
Instead, you should record the DateTime
instants in UTC, which gives you the date and time as it is in the Coordinated Universal Time.
UTC is a time standard for all time zones and is not subjected to Daylight Saving Time (DST).
Similarly, the use of the DateTime.Today
property should also be avoided, as it can return different date values depending on the time
zone.
Generally, unless the purpose is to only display the Date and Time to a user on their local machine, you should always use UTC (for example, when
storing dates in a datebase or using them for calculations).
What is the potential impact?
You can end up with DateTime
instants that have no meaning for anyone except the machine they were recorded on. Using UTC gives an
unambiguous representation of an instant, and this UTC instant can be transformed into any equivalent local time. This operation isn’t reversible as
some local times are ambiguous and can be matched to more than one UTC instant (for example, due to daylight savings).
How to fix it
Instead of DateTime.Now
use any of the following:
-
DateTime.UtcNow
,
-
DateTimeOffSet.Now
(as it contains offset information)
-
DateTimeOffSet.UtcNow
Instead of DateTime.Today
use any of the following:
-
DateTime.UtcNow.Date
,
-
DateOnly.FromDateTime(DateTime.UtcNow)
(.NET 6.0+)
Code examples
Noncompliant code example
void LogDateTime()
{
using var streamWriter = new StreamWriter("logs.txt", true);
streamWriter.WriteLine($"DateTime:{DateTime.Now.ToString("o")}"); // This log won't have any meaning if it's reconstructed in a machine in a different timezone.
}
Compliant solution
void LogDateTime()
{
using var streamWriter = new StreamWriter("logs.txt", true);
streamWriter.WriteLine($"DateTime:{DateTime.UtcNow.ToString("o")}");
}
Resources
Documentation
- DateTime.Now documentation
- DateTime.UtcNow documentation
- DateTime.Today documentation
- DateTimeOffset documentation
- Ambiguous times
- UTC standard
Articles & blog posts