EF Core DateTimeOffset offset preserved instead of converted to regional time zone
0 reputation · 10 Mar 2020, 03:07 UTC
0 reputation · 10 Mar 2020, 03:07 UTC
Goal: persist an entity DateTimeOffset property carrying a specific regional offset and read it back with that offset unchanged.
EF Core does not automatically normalize DateTime or DateTimeOffset values to UTC or a chosen regional time zone on save or load. DateTimeKind is generally preserved, and interpretation is left to the provider and application code. Providers also differ: SQL Server datetimeoffset retains the offset, while datetime maps to DateTime with possible rounding, and PostgreSQL timestamp with time zone may normalize to UTC server-side depending on the column type. EF Core 6+ adds DateOnly and TimeOnly, but these do not provide built-in regional DateTime conversion; HasConversion is required for explicit logic.
Uncertainty: whether a single entity model can rely on consistent offset behavior across SQL Server, SQLite, and PostgreSQL without provider-specific configuration, and where conversion should occur relative to change tracking and materialization.
EF Core does not convert a DateTimeOffset value to another time zone when you call SaveChanges or when the entity is materialized. The value that is sent to the database, and the value that comes back, contain the same Offset component that was supplied in the application code.
datetimeoffset column type in SQL Server, the timestamptz type in PostgreSQL, and the text representation used by SQLite all store the offset as part of the value.DateTimeOffset is a round‑trippable value converter that simply writes the value unchanged to the column and reads it back unchanged.DateTimeOffset already carries its own offset, DateTimeKind is irrelevant – the Kind property of a DateTimeOffset instance is always Unspecified, but the offset field is preserved.ValueConverter that changes the offset (e.g., normalises to UTC), that logic will be applied on both write and read, but it is explicit and not automatic.datetimeoffset; in PostgreSQL it should be timestamptz; in SQLite it should be a string that contains the offset (e.g., 2026-10-18T01:47:03+02:00).ValueConverter that changes the offset, remove it or make it round‑trippable.DateTimeOffset with a non‑UTC offset, call SaveChanges, then query the entity again and compare the Offset property. It should match the original value.HasConversion only when you explicitly want to store a different representation (e.g., UTC). In that case, the converter must be invertible so change tracking continues to work correctly.If your application logic requires that every DateTimeOffset be stored with a specific regional offset (e.g., +02:00), then you must implement a ValueConverter that forces that offset before saving and restores the original offset when reading back. This is an explicit step, not an automatic EF Core feature.
To tailor the recommendation exactly, could you confirm which database provider you are targeting? If you are using SQLite, the driver’s conversion rules can differ from SQL Server and PostgreSQL.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.