Skip to content

Conversation

vzakanj
Copy link

@vzakanj vzakanj commented Sep 8, 2025

Fixes #2866

When using default NodaTime serialization, the Instant is serialized using the ExtendedIso (uuuu'-'MM'-'dd'T'HH':'mm':'ss;FFFFFFFFF'Z') format and is saved as such to the data jsonb column.

But when the data is read and deserialized the Instant format depends on how the data is read:

  1. When the Instant is read as a part of a parent object e.g. session.Query<ParentObj>().SingleAsync(p => p.Id = fooId) then the jsonb is read as is and the Instant property is formatted as an ExtendedIso string - not an issue
  2. But when the Instant is read by using LINQ Select to project only specific properties from the data column (e.g. session.Query<ParentObj>().Select(p => new { p.Id, p.InstantProp }).SingleAsync()), in the SQL SELECT statement, the properties are cast to the Npgsql type the property type maps to.
    Instant maps to timestamp with time zone and when the cast is performed, the format contains the +00:00 offset at the end instead of the Z, so the deserialization attempt with the ExtendedIso format fails

I've added the InstantJsonConverter for both STJ and Newtonsoft which tries the alternate format deserialization if the ExtendedIso deserialization fails, and have registered it as the Instant converter instead of the default NodaPatternConverter<Instant> when UseNodaTime is called.

This shouldn't be a breaking change, but I've made the InstantJsonConverter public to make it easier to remove and replace with a custom converter when needed.
Let me know if you think making it internal is the better decision choice.

@jeremydmiller
Copy link
Member

@vzakanj Hey, can you double check this? It's failing on the NodaTime tests

@vzakanj
Copy link
Author

vzakanj commented Sep 17, 2025

Looking at the test assertion error below, it seems like it's a precision issue that I'm not able to reproduce locally, i.e. those two tests are passing on my machine.

I'll look into into it in more detail and update the PR when I have the fix.

20:19:59 [DBG]   Failed Marten.NodaTimePlugin.Testing.Acceptance.noda_time_acceptance.bug_1276_can_select_instant(serializerType: Newtonsoft) [248 ms]
  20:19:59 [DBG]   Error Message:
  20:19:59 [DBG]    Shouldly.ShouldAssertException : resultWithSelect.InstantUTC
  20:19:59 [DBG]     should be
  20:19:59 [DBG] 2025-09-16T20:19:59Z
  20:19:59 [DBG]     but was
  20:19:59 [DBG] 2025-09-16T20:19:59Z

@vzakanj vzakanj force-pushed the bug/2866-nodatime-instant-serialization branch from aafb63b to ed4a74d Compare September 17, 2025 01:13
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.

NodaTime projection deserialization exception

2 participants