← 返回首页
Unsafe year argument for ‘DateTime’ constructor — CodeQL query help documentation CodeQL docs
CodeQL documentation
CodeQL resources

Unsafe year argument for ‘DateTime’ constructor

ID: cs/unsafe-year-construction Kind: path-problem Security severity: Severity: warning Precision: medium Tags: - quality - reliability - correctness Query suites: - csharp-security-and-quality.qls

Click to see the query in the CodeQL repository

When creating a System.DateTime object by setting the year, month, and day in the constructor by performing an arithmetic operation on a different DateTime object, there is a risk that the date you are setting is invalid.

On a leap year, such code may throw an ArgumentOutOfRangeException with a message of "Year, Month, and Day parameters describe an unrepresentable DateTime."

Recommendation

Creating a System.DateTime object based on a different System.DateTime object, use the appropriate methods to manipulate the date instead of arithmetic.

Example

In this example, we are incrementing/decrementing the current date by one year when creating a new System.DateTime object. This may work most of the time, but on any given February 29th, the resulting value will be invalid.

using System; public class UnsafeYearConstructionBad { public UnsafeYearConstructionBad() { DateTime Start; DateTime End; var now = DateTime.UtcNow; // the base-date +/- n years may not be a valid date. Start = new DateTime(now.Year - 1, now.Month, now.Day, 0, 0, 0, DateTimeKind.Utc); End = new DateTime(now.Year + 1, now.Month, now.Day, 0, 0, 1, DateTimeKind.Utc); } }

To fix this bug, we add/subtract years to the current date by calling AddYears method on it.

using System; public class UnsafeYearConstructionGood { public UnsafeYearConstructionGood() { DateTime Start; DateTime End; var now = DateTime.UtcNow; Start = now.AddYears(-1).Date; End = now.AddYears(-1).Date.AddSeconds(1); } }

References