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}