Skip to content

feat(csharp): option to suppress DateOnly/TimeOnly converters (System.Text.Json)#2962

Merged
schani merged 1 commit into
masterfrom
csharp-dateonly-optout
Jul 20, 2026
Merged

feat(csharp): option to suppress DateOnly/TimeOnly converters (System.Text.Json)#2962
schani merged 1 commit into
masterfrom
csharp-dateonly-optout

Conversation

@schani

@schani schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Supersedes #2842, fixes #2629.

This is a reimplementation of @findyoucef's PR #2842, which could not be rebased (conflicts with the C# 8 default work plus unrelated dependency churn). The core idea — making the System.Text.Json DateOnly/TimeOnly converter emission optional — is theirs; their authorship is preserved via a Co-authored-by trailer on the commit.

Problem

The System.Text.Json C# renderer unconditionally emits DateOnlyConverter and TimeOnlyConverter helper classes and registers them in Converter.Settings. DateOnly/TimeOnly only exist on .NET 6+, so the generated code does not compile on .NET Standard or older target frameworks (#2629).

Change

A new System.Text.Json-only boolean option:

--[no-]dateonly-timeonly-converters    Emit DateOnly/TimeOnly converters (requires .NET 6 or later) (on by default)

With --no-dateonly-timeonly-converters, both converter classes and their Converters = { ... } registrations are omitted. Nothing else in the generated code references them, so the output still compiles and round-trips. Default output is byte-for-byte identical to master.

The option lives in systemTextJsonCSharpOptions rather than the shared cSharpOptions, so only the System.Text.Json renderer's typed options include it — it is not a silent no-op field on the Newtonsoft options object (the original PR put its flags in the shared options). CSharpTargetLanguage.getOptions() now returns the System.Text.Json superset so the CLI accepts and documents the flag.

Kept from #2842 vs. dropped

  • Kept: conditional emission and registration of the two converters, gated on a renderer option — as one flag instead of the original two (no-dateonly/no-timeonly), since DateOnly and TimeOnly were introduced together in .NET 6 and no target wants only one of them.
  • Dropped: the csTypeLocal DateOnly→DateTime / TimeOnly→TimeSpan remapping helper (dead code — the C# type mapper never produces DateOnly/TimeOnly property types; dates map to DateTimeOffset); the package.json/package-lock.json dependency bumps; .vscode/tasks.json; and the whitespace reformat of the converter boilerplate (keeping default output byte-identical).

Testing

  • Fixture: csharp-SystemTextJson gains a pinned quick-test — unions.json with dateonly-timeonly-converters: false — proving that generated code with the converters suppressed still compiles and round-trips.
  • Unit test test/unit/csharp-dateonly-timeonly-converters.test.ts: default output contains both converter classes and registrations; with the flag set it contains neither, while IsoDateTimeOffsetConverter is unaffected.
  • Locally green: FIXTURE=csharp-SystemTextJson (236/236 samples), FIXTURE=schema-csharp-SystemTextJson, FIXTURE=csharp, FIXTURE=schema-csharp, and npm run test:unit (165 tests, type tests included).

🤖 Generated with Claude Code

….Text.Json)

The System.Text.Json C# renderer unconditionally emits DateOnlyConverter
and TimeOnlyConverter helper classes and registers them in
Converter.Settings.  DateOnly and TimeOnly only exist on .NET 6+, so the
generated code does not compile on .NET Standard or older targets
(issue #2629).

Add a System.Text.Json-only boolean option,
--[no-]dateonly-timeonly-converters (on by default), that suppresses
both the converter classes and their registration.  Nothing else in the
generated code references them, so suppressed output still compiles and
round-trips; default output is byte-for-byte identical.

The option lives in systemTextJsonCSharpOptions rather than the shared
cSharpOptions, so only the System.Text.Json renderer's typed options
include it; CSharpTargetLanguage.getOptions() now returns the
System.Text.Json superset so the CLI accepts the flag.

Covered by a pinned csharp-SystemTextJson quick-test (unions.json with
the converters suppressed must compile and round-trip) and a unit test
asserting the converter classes' presence by default and absence under
the flag.

Reimplementation of #2842 by youcefnb (findyoucef); supersedes it.
Fixes #2629.

Co-authored-by: youcefnb <youcef@colorado.edu>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@schani
schani merged commit 6d81f82 into master Jul 20, 2026
28 checks passed
@schani
schani deleted the csharp-dateonly-optout branch July 20, 2026 16:49
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.

[FEATURE]: CSharp - make emitting DateOnlyConverter & TimeOnlyConverter optional

1 participant