Skip to content

MA0113: Only report DateTime constructors with the Utc kind - #1458

Merged
meziantou merged 1 commit into
mainfrom
feature/ma0113-datetime-kind-3ffd55
Sep 11, 2026
Merged

meziantou merged 1 commit into
mainfrom
feature/ma0113-datetime-kind-3ffd55

Conversation

@meziantou

Copy link
Copy Markdown
Owner

Problem

MA0113 reported DateTime constructors that don't take a DateTimeKind, and its fix replaced them with DateTime.UnixEpoch:

public static object Run() => new System.DateTime(1970, 1, 1).Kind;
// fixed to
public static object Run() => System.DateTime.UnixEpoch.Kind;

Both compile, but the first returns DateTimeKind.Unspecified and the second returns DateTimeKind.Utc. The ticks are equal, but the values aren't interchangeable. The kind matters to code that inspects Kind, converts between time zones, or serializes the kind.

Changes

  • Analyzer: removed the branches for new DateTime(ticks), new DateTime(1970, 1, 1) and new DateTime(1970, 1, 1, 0, 0, 0). The rule now only reports constructors that explicitly pass DateTimeKind.Utc. It also recognizes the millisecond and microsecond overloads with DateTimeKind.Utc, which MA0114 already handles for DateTimeOffset.
  • Tests: the constructors that don't set a kind are now "no diagnostic" cases, including the repro above. New cases cover the Local and Unspecified kinds, non-zero milliseconds and microseconds, and the Calendar overload. The old-framework test now uses a UTC constructor, so it still checks that nothing is reported when DateTime.UnixEpoch doesn't exist.
  • Docs: MA0113.md no longer recommends replacing new DateTime(1970, 1, 1). It explains why constructors without an explicit DateTimeKind.Utc aren't reported.

Notes for reviewers

  • MA0113 now reports fewer cases: code that relied on it for new DateTime(1970, 1, 1) won't get a diagnostic anymore. That's intended, because the fix would have changed behavior.
  • MA0114 (DateTimeOffset) is unchanged. DateTimeOffset has no kind, and every case it reports requires a zero offset.

Testing

  • UseDateTimeUnixEpochAnalyzerTests passes on Roslyn 4.8, 4.14, 5.0, 5.6 and 5.9 (45 tests each).
  • dotnet run --project src/DocumentationGenerator exits 0 and generates no further changes.

DateTime.UnixEpoch has the DateTimeKind.Utc kind, while the constructors
without a DateTimeKind argument create a DateTimeKind.Unspecified value.
Replacing them with DateTime.UnixEpoch changed the Kind of the value,
which affects time zone conversions and serialization.

The rule now only reports the constructors that explicitly pass
DateTimeKind.Utc, and also handles the millisecond and microsecond
overloads, as MA0114 does for DateTimeOffset.
@meziantou
meziantou merged commit f8564de into main Sep 11, 2026
13 checks passed
@meziantou
meziantou deleted the feature/ma0113-datetime-kind-3ffd55 branch September 11, 2026 19:20
This was referenced Sep 11, 2026
This was referenced Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant