Skip to content

Add the net10 ISOWeek DateOnly overloads - #601

Merged
SimonCropp merged 1 commit into
mainfrom
isoweek-dateonly
Sep 10, 2026
Merged

Add the net10 ISOWeek DateOnly overloads#601
SimonCropp merged 1 commit into
mainfrom
isoweek-dateonly

Conversation

@SimonCropp

Copy link
Copy Markdown
Owner

Three members: GetWeekOfYear(DateOnly), GetYear(DateOnly) and ToDateOnly(int, int, DayOfWeek).

Version and window

These are net10, not net9 as the shortlist had them — absent from the 9.0.20 ref pack, present in 10.0.12. The polyfillable window is bounded at the bottom by DateOnly, which is net6.0 and which Polyfill does not recreate, so the range is net6.0 through net9.0. Each member carries a //Note: saying so, since #### ISOWeek gives no hint of a floor.

Worth noting the type itself has a different floor again: ISOWeek is netstandard2.1/netcoreapp3.0, so net461–net481 and netstandard2.0 have no ISOWeek at all. Recreating it is a separate question and not attempted here.

Implementation

Each delegates to the DateTime overload that has been on ISOWeek since netcoreapp3.0, so both the result and the argument validation come from the BCL rather than being reimplemented. ToDateOnly is DateOnly.FromDateTime(ISOWeek.ToDateTime(...)).

That also reproduces one BCL quirk exactly, by construction: ToDateOnly(9999, 52, DayOfWeek.Sunday) runs off the end of the representable range and reports ArgumentOutOfRangeException with param value and the message "The added or subtracted value results in an un-representable DateTime" — a DateTime message from a DateOnly-returning API. net10 does the same thing for the same reason, and there is a test pinning it.

Verified exhaustively, before writing the code

  • All 3 652 059 representable dates, 0001-01-01 to 9999-12-31, agree with the DateTime overloads for both GetWeekOfYear and GetYear.
  • All 3 652 061 (year, week, day) combinations across every ISO week of every year agree with DateOnly.FromDateTime(ToDateTime(...)), including every case where both throw.
  • Argument validation is identical to ToDateTime — same types, paramNames and messages for out-of-range year, week and DayOfWeek.

Zero mismatches in all of it.

The tests assert how much they swept

Both sweeps count the combinations visited and assert the total. That is not decoration: on the first run the count assertion failed, which is what proved the loops were genuinely executing rather than being elided, and pinned the real combination count. Without it, a future edit that narrowed the bounds would leave a green test that checks almost nothing. The whole thing runs in about 250ms, so exhaustive is affordable here.

Verification

Solution clean in Release, Consume clean across all 22 TFMs, tests green on net11.0 (1718), net10.0 (1718), net9.0 (1718), net8.0 (1715), net462 (1665), plus PublicTests, EmbeddedTests, UnsafeTests, NoRefsTests and NoExtrasTests.

net7.0 (1703) and net6.0-windows (1682) were run on the net11 runtime with dotnet exec --roll-forward LatestMajor, since those runtimes are not installed on this machine — both are inside the polyfill's window, so this exercises the polyfill rather than the BCL.

API count 1147 → 1150.

Three members: GetWeekOfYear, GetYear and ToDateOnly. These are net10 rather than
net9, and the polyfillable window is net6.0 through net9.0, since DateOnly arrives in
net6.0 and Polyfill does not recreate it. Noted on each.

Each delegates to the DateTime overload that has been on ISOWeek since netcoreapp3.0,
so the result and the argument validation both come from the BCL.

Verified exhaustively against net11 before writing anything: all 3652059 representable
dates agree with the DateTime overloads for both GetWeekOfYear and GetYear, and all
3652061 year, week and day combinations agree with
DateOnly.FromDateTime(ToDateTime(...)), including the cases where both throw.

The tests repeat both sweeps and assert the number of combinations visited, so a future
edit cannot quietly shrink them. That assertion caught the sweep count being wrong on
the first run, which was also the proof that the loops execute rather than being
optimised away.

net6.0 and net7.0 were run on the net11 runtime with roll forward, since those runtimes
are not installed here.

API count 1147 -> 1150.
@SimonCropp SimonCropp added this to the 11.3.0 milestone Sep 10, 2026
@SimonCropp
SimonCropp merged commit c7d6b27 into main Sep 10, 2026
4 of 6 checks passed
@SimonCropp
SimonCropp deleted the isoweek-dateonly branch September 10, 2026 08:52
This was referenced Sep 10, 2026
This was referenced Sep 11, 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