apalis_sql/datetime.rs
1//! DateTime abstraction for unified time handling.
2//!
3//! This module provides a unified API for datetime operations in the SQL backends,
4//! abstracting over the differences between the `chrono` and `time` crates.
5//!
6//! # Feature Flags
7//!
8//! The datetime implementation is selected based on enabled features:
9//!
10//! - **`time` feature enabled**: Uses `time::OffsetDateTime` as the underlying type.
11//! This takes precedence even if `chrono` is also enabled.
12//! - **`chrono` feature enabled (without `time`)**: Uses `chrono::DateTime<Utc>`.
13//!
14//! # Why This Abstraction?
15//!
16//! Different SQL database drivers have varying levels of support for datetime crates.
17//! Some work better with `chrono`, others with `time`. This module allows users to
18//! choose the datetime crate that best fits their database driver and application
19//! needs, while the rest of the codebase uses a consistent API through the
20//! [`DateTimeExt`] trait.
21//!
22//! # Usage
23//!
24//! ```rust
25//! use apalis_sql::{DateTime, DateTimeExt};
26//!
27//! // Get current time (works with either feature)
28//! let now = DateTime::now();
29//!
30//! // Convert to Unix timestamp
31//! let timestamp = now.to_unix_timestamp();
32//!
33//! // Create from Unix timestamp
34//! let dt = DateTime::from_unix_timestamp(timestamp);
35//! ```
36
37/// DateTime type alias that uses either chrono or time depending on enabled features.
38///
39/// When the `time` feature is enabled, this is `time::OffsetDateTime`.
40/// When the `chrono` feature is enabled (and `time` is not), this is `chrono::DateTime<Utc>`.
41#[cfg(all(feature = "chrono", not(feature = "time")))]
42pub type DateTime = chrono::DateTime<chrono::Utc>;
43
44/// DateTime type alias that uses either chrono or time depending on enabled features.
45///
46/// When the `time` feature is enabled, this is `time::OffsetDateTime`.
47/// When the `chrono` feature is enabled (and `time` is not), this is `chrono::DateTime<Utc>`.
48#[cfg(feature = "time")]
49pub type DateTime = time::OffsetDateTime;
50
51/// Extension trait for SQL datetime operations.
52///
53/// This trait provides a unified API for datetime operations regardless of
54/// whether `chrono` or `time` feature is enabled.
55pub trait DateTimeExt {
56 /// Returns the current UTC datetime.
57 fn now() -> Self;
58
59 /// Returns the Unix timestamp (seconds since epoch).
60 fn to_unix_timestamp(&self) -> i64;
61
62 /// Creates a datetime from Unix timestamp (seconds since epoch).
63 fn from_unix_timestamp(secs: i64) -> Self;
64}
65
66#[cfg(all(feature = "chrono", not(feature = "time")))]
67impl DateTimeExt for DateTime {
68 fn now() -> Self {
69 chrono::Utc::now()
70 }
71
72 fn to_unix_timestamp(&self) -> i64 {
73 self.timestamp()
74 }
75
76 fn from_unix_timestamp(secs: i64) -> Self {
77 DateTime::from_timestamp(secs, 0).unwrap_or_default()
78 }
79}
80
81#[cfg(feature = "time")]
82impl DateTimeExt for DateTime {
83 fn now() -> Self {
84 Self::now_utc()
85 }
86
87 fn to_unix_timestamp(&self) -> i64 {
88 self.unix_timestamp()
89 }
90
91 fn from_unix_timestamp(secs: i64) -> Self {
92 Self::from_unix_timestamp(secs).unwrap_or(Self::UNIX_EPOCH)
93 }
94}