-
-
Notifications
You must be signed in to change notification settings - Fork 9
Comparing changes
Open a pull request
base repository: NpgsqlRest/NpgsqlRest
base: 3.15.2
head repository: NpgsqlRest/NpgsqlRest
compare: 3.16.0
- 5 commits
- 24 files changed
- 2 contributors
Commits on May 20, 2026
-
feat: v3.16.0 — datetime parsers are now host-TZ-independent
The four JSON-to-parameter parsers for timestamp / timestamptz / time / timetz used the bare DateTime.TryParse(value) overload, which converts offset-bearing strings to host-local time and tags Kind=Local. The two *Tz parsers then called SpecifyKind(v, Utc) on the local-shifted value — SpecifyKind only relabels Kind, it does not convert — so a host-local wall-clock value got sent to Postgres labelled UTC. The timestamp/time parsers sent the local-shifted value directly to Npgsql, which transmits the wall-clock verbatim for `without time zone` columns. Net effect on any non-UTC host: stored values silently shifted by the host's UTC offset. All four parsers now use DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal: naive ISO strings are assumed UTC, Z- and offset-bearing strings are converted to UTC. TryParseTimestamp strips Kind to Unspecified so Npgsql ships UTC clock-time as the naive wall-clock value. TryParseDate is unchanged — DateOnly.TryParse rejects Z/offset strings outright and does not silently shift. Breaking (minor bump, not patch): naive JSON timestamps (no Z, no offset) are now treated as UTC rather than host-local. Callers on UTC hosts see no change. Callers who sent Z strings expecting UTC were broken on non-UTC hosts and are now correct. New NpgsqlRestTests/HostTimeZoneIndependenceTests covers all four parsers via echo-function round-trips. Verified passing under both TZ=UTC and TZ=America/Los_Angeles. Existing MultiParamsTests2 / MultiParamsQueryStringTests2 had Should().Match(...) workarounds for exactly this bug — now tightened to single-value Should().Be(...). Also bumps NuGet references (FluentAssertions, WireMock.Net, Microsoft.AspNetCore.Mvc.Testing, Microsoft.NET.Test.Sdk, coverlet.collector, Microsoft.SourceLink.GitHub) across test + plugin projects. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 8d3f834 - Browse repository at this point
Copy the full SHA 8d3f834View commit details -
bump version strings to 3.16.0
The previous squash committed the staged (3.15.3) version of these files but left the 3.16.0 working-tree edits unstaged. This commit catches them up. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for ccbab12 - Browse repository at this point
Copy the full SHA ccbab12View commit details -
feat: add JsonTimestampsAreUtc opt-out for legacy host-local behavior
Adds a compatibility escape hatch for the breaking change introduced by the v3.16.0 datetime-parser fix. When set to false, the four parsers revert to the bare DateTime.TryParse(value) overload — restoring the pre-3.16.0 code path verbatim (Z/offset strings get host-local-shifted, naive strings get Kind=Unspecified, *Tz parsers apply SpecifyKind(Utc) on top). Default is true (the new, correct behavior). - NpgsqlRestOptions.JsonTimestampsAreUtc (bool, default true) — new top-level option on the library. - ParameterParsers.JsonTimestampsAreUtc static field — process-wide toggle, set from options in NpgsqlRestBuilder. Matches the existing static-class pattern of ParameterParsers. - Client config wiring: ConfigDefaults / ConfigTemplate / ConfigSchemaGenerator entries plus Program.cs reads via GetConfigBool("JsonTimestampsAreUtc", ..., true). Six new unit tests verify the plumbing: flag defaults to true, can be toggled, parsers still produce valid results for all four type variants in legacy mode, and invalid input still returns false. Tests are placed in the TestFixture collection so static-state mutations are serialized against the integration suite. (Real behavioral coverage of legacy mode requires a non-UTC TZ environment; on UTC hosts both modes produce the same wire-level output.) Changelog v3.16.0 gains an "Opt-out" section documenting the flag and explaining why it is not recommended for new deployments. Co-Authored-By: Claude Opus 4.7 <[email protected]>Configuration menu - View commit details
-
Copy full SHA for 4cb5cd4 - Browse repository at this point
Copy the full SHA 4cb5cd4View commit details -
sync appsettings.json with JsonTimestampsAreUtc opt-out
appsettings.json is the source of truth; ConfigTemplate.cs mirrors it. The previous commit added the entry to ConfigTemplate.cs but missed appsettings.json itself. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 0158fb9 - Browse repository at this point
Copy the full SHA 0158fb9View commit details -
feat: TryParseDate accepts Z- and offset-bearing strings
DateOnly.TryParse rejects any ISO string carrying a Z suffix or numeric offset (e.g. "2026-05-20T03:00:00Z") outright, returning false. That left callers who send full ISO timestamps to a date parameter with a flat parse failure — they had to strip the time portion client-side or the request died before reaching Postgres. TryParseDate now keeps DateOnly.TryParse as the fast path (unchanged behavior for naked dates and naive date-time strings) and falls back to DateTime.TryParse + DateOnly.FromDateTime for Z- and offset-bearing inputs. The fallback honors JsonTimestampsAreUtc: when true it uses AssumeUniversal | AdjustToUniversal so the extracted date is the UTC calendar day; when false it uses bare DateTime.TryParse so the date matches the host's local calendar day. Strictly broader accepted-input set, zero change for inputs that already worked. Five new tests in HostTimeZoneIndependenceTests cover: bare date, naive date-time, Z-suffix early UTC, +02:00 offset crossing midnight, and a Z-suffix late-evening case that the legacy parser would have rejected entirely. Companion echo function host_tz_echo_date added to Database setup. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for f350c7e - Browse repository at this point
Copy the full SHA f350c7eView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 3.15.2...3.16.0