From 419877d73403d96914937b3fd9021ce53e40682a Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Sun, 8 Sep 2024 21:53:10 -0700 Subject: [PATCH] doc(sqlite): document behavior for zoned date-time types (#3493) --- sqlx-sqlite/src/types/mod.rs | 62 +++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/sqlx-sqlite/src/types/mod.rs b/sqlx-sqlite/src/types/mod.rs index eae1c59c..d36af7ea 100644 --- a/sqlx-sqlite/src/types/mod.rs +++ b/sqlx-sqlite/src/types/mod.rs @@ -65,7 +65,36 @@ //! November 24, 4714 BCE 12:00 UTC, as if returned from the `julianday()` function. //! //! These types will always encode to a datetime string, either -//! with (`DateTime` for any `Tz: TimeZone`) or without (`NaiveDateTime`) a timezone offset. +//! with a timezone offset (`DateTime` for any `Tz: TimeZone`) or without (`NaiveDateTime`). +//! +//! ##### NOTE: `CURRENT_TIMESTAMP` and comparison/interoperability of `DATETIME` values +//! As stated previously, `DateTime` always encodes to a date-time string +//! _with_ a timezone offset, +//! in [RFC 3339 format][::chrono::DateTime::to_rfc3339_opts] (with `use_z: false`). +//! +//! However, most of SQLite's datetime functions +//! (including `datetime()` and `DEFAULT CURRENT_TIMESTAMP`) +//! do not use this format. They instead use `YYYY-MM-DD HH:MM:SS.SSSS` without a timezone offset. +//! +//! This may cause problems with interoperability with other applications, and especially +//! when comparing datetime values, which compares the actual string values lexicographically. +//! +//! Date-time strings in the SQLite format will generally _not_ compare consistently +//! with date-time strings in the RFC 3339 format. +//! +//! We recommend that you decide up-front whether `DATETIME` values should be stored +//! with explicit time zones or not, and use the corresponding type +//! (and its corresponding offset, if applicable) _consistently_ throughout your +//! application: +//! +//! * RFC 3339 format: `DateTime` (e.g. `DateTime`, `DateTime`, `DateTime`) +//! * Changing or mixing and matching offsets may break comparisons with existing timestamps. +//! * `DateTime` is **not recommended** for portable applications. +//! * `DateTime` is only recommended if the offset is **constant**. +//! * SQLite format: `NaiveDateTime` +//! +//! Note that non-constant offsets may still cause issues when comparing timestamps, +//! as the comparison operators are not timezone-aware. //! //! ### [`time`](https://crates.io/crates/time) //! @@ -82,6 +111,37 @@ //! The behavior here is identical to the corresponding `chrono` types, minus the support for `REAL` //! values as Julian days (it's just not implemented). //! +//! `PrimitiveDateTime` and `OffsetDateTime` will always encode to a datetime string, either +//! with a timezone offset (`OffsetDateTime`) or without (`PrimitiveDateTime`). +//! +//! ##### NOTE: `CURRENT_TIMESTAMP` and comparison/interoperability of `DATETIME` values +//! As stated previously, `OffsetDateTime` always encodes to a datetime string _with_ a timezone offset, +//! in [RFC 3339 format][::time::format_description::well_known::Rfc3339] (using `Z` for UTC offsets). +//! +//! However, most of SQLite's datetime functions +//! (including `datetime()` and `DEFAULT CURRENT_TIMESTAMP`) +//! do not use this format. They instead use `YYYY-MM-DD HH:MM:SS.SSSS` without a timezone offset. +//! +//! This may cause problems with interoperability with other applications, and especially +//! when comparing datetime values, which compares the actual string values lexicographically. +//! +//! Date-time strings in the SQLite format will generally _not_ compare consistently +//! with date-time strings in the RFC 3339 format. +//! +//! We recommend that you decide up-front whether `DATETIME` values should be stored +//! with explicit time zones or not, and use the corresponding type +//! (and its corresponding offset, if applicable) _consistently_ throughout your +//! application: +//! +//! * RFC 3339 format: `OffsetDateTime` with a **constant** offset. +//! * Changing or mixing and matching offsets may break comparisons with existing timestamps. +//! * `OffsetDateTime::now_local()` is **not recommended** for portable applications. +//! * Non-UTC offsets are only recommended if the offset is **constant**. +//! * SQLite format: `PrimitiveDateTime` +//! +//! Note that non-constant offsets may still cause issues when comparing timestamps, +//! as the comparison operators are not timezone-aware. +//! //! ### [`uuid`](https://crates.io/crates/uuid) //! //! Requires the `uuid` Cargo feature flag.