Skip to content

Latest commit

 

History

History
39 lines (25 loc) · 2.56 KB

DateTime-handling.md

File metadata and controls

39 lines (25 loc) · 2.56 KB

Overview

  • Backend sends all data in UTC, and accepts data in LOCAL client timezones.
  • The frontend could send dates to backend either:
    • in UTC (that's what JS does by default)
    • in local client timezone with timezone specified, e.g. '2023-04-28T02:02:41.605+07:00' (that's what we do in our frontend by overriding Date.prototype.toISOString = in index.tsx)
  • Database - all values are in UTC.
  • Backend - all values are in UTC.
  • Client - all values are in LOCAL timezone (converted from UTC automatically on deserialization. when serializing - no conversion to UTC is made).

We only use DateTime class on backend (never use DateTimeOffset).

This aligns with recommendations npgsql/npgsql#2209 (comment)

Working with timezone-aware databases is a headache. Whenever possible, we recommend that users go turtles UTC all the way down. That is, only convert from/to local time when displaying to a human user.

TL/DR

  • Use DateOnly if you want to store only the dates (independent of the TimeZone).
  • Use DateTime if you want to store Date with Time. It will be always in UTC on backend.
  • Never use DateTimeOffset.

Handling DateTime (with time)

  • Client need to send the datetime using local timezone, i.e. 2021-01-23T17:30:00+07:00 should be sent over http.
  • Backend upon deserialization will convert the date to UTC. I.e. on backend it will be 2021-01-23T10:30:00. Since we use DateTime (not DateTimeOffset) no timezone is specified. All values on backend are in UTC.
  • In GET requests the server sends values in UTC, i.e. the following will be sent: 2021-01-23T10:30:00+00:00. Client will know it's UTC (by the trailing +00:00) and will convert it to local time, 2021-01-23T17:30:00+07:00.

Handling DateOnly (without time)

If certain property contains only Date (without time), e.g. BirthDate, it must be of DateOnly type. In this case everything is handled automatically (by DateOnlyConverters and autogenerated clients). DateOnly fields are serialized as yyyy-MM-dd (both from Frontend and Backend side).

Handling DateTimeOffset

We do NOT use DateTimeOffset at all.

Rationale

PostgreSQL doesn't store timezone offset, and Npgsql requires that all DateTimeOffset have Zero offset (otherwise it throws an exception upon saving). So, if you always have to use Zero offset, using DateTimeOffset type doesn't make any sense and only brings confusion (because it seems like you could use different time zones, while in reality you could not).