diff options
| author | Joe Carstairs <me@joeac.net> | 2024-10-30 07:27:13 +0000 |
|---|---|---|
| committer | Joe Carstairs <me@joeac.net> | 2024-10-30 08:50:45 +0000 |
| commit | 828b9ae9f6217f7e5e97ec704134c786dd401bad (patch) | |
| tree | c920b8874682e89ba05b6e1ca20275bfd5878d87 /backend/core/src/models/date_time_utc.rs | |
| parent | 6e9f0069f5d1e4cfbf7f9feb8536795a78c818f6 (diff) | |
Separates date_utc and datetime_utc
Diffstat (limited to 'backend/core/src/models/date_time_utc.rs')
| -rw-r--r-- | backend/core/src/models/date_time_utc.rs | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/backend/core/src/models/date_time_utc.rs b/backend/core/src/models/date_time_utc.rs deleted file mode 100644 index d59d8f4..0000000 --- a/backend/core/src/models/date_time_utc.rs +++ /dev/null @@ -1,182 +0,0 @@ -use anyhow::{Error, Result}; -use chrono::{DateTime, Datelike, Utc}; -use diesel::{ - backend::Backend, - deserialize::{self, FromSql, FromSqlRow}, - expression::AsExpression, - serialize::{self, ToSql}, - sql_types::Text, - sqlite::Sqlite, -}; -use serde::{Deserialize, Serialize}; - -#[derive( - Eq, - PartialEq, - Ord, - PartialOrd, - Serialize, - Deserialize, - Clone, - Debug, - AsExpression, - FromSqlRow, -)] -#[diesel(sql_type=Text)] -pub struct DateTimeUtc { - chrono_datetime_utc: DateTime<Utc>, -} - -impl DateTimeUtc { - pub fn day_diff(&self, other: &DateTimeUtc) -> u32 { - self.chrono_datetime_utc - .num_days_from_ce() - .abs_diff(other.chrono_datetime_utc.num_days_from_ce()) - } - - pub fn new(chrono_datetime_utc: &DateTime<Utc>) -> Self { - Self { - chrono_datetime_utc: chrono_datetime_utc.clone(), - } - } - - pub fn now() -> Self { - Self::new(&Utc::now()) - } - - /// Constructs DateTimeUtc from a day string, YYYY-MM-DD, in UTC - /// Example: "2024-10-24" -> Midnight 24 Oct 2024 UTC - pub fn from_day_str(day_str: &str) -> Result<Self> { - if !Self::is_day_str(day_str) { - Err(Error::msg(format!("{} is not a day string in YYYY-MM-DD format", day_str))) - } else { - let mut date_str = String::from(day_str); - date_str.push_str("T00:00:00.000Z"); - Ok(Self::from_date_str(&date_str)?) - } - } - - /// Constructs DateTimeUtc from a date string in ISO format, in UTC - /// Example: "2024-10-24T10:30:00.000" -> 10.30am 24 Oct 2024 UTC - pub fn from_date_str(date_time_utc: &str) -> Result<Self> { - let chrono_datetime_utc = date_time_utc.parse::<DateTime<Utc>>()?; - Ok(Self { - chrono_datetime_utc, - }) - } - - /// Converts to a day string, YYYY-MM-DD, in UTC - /// Example: 10.30am 24 Oct 2024 UTC -> "2024-10-24" - pub fn to_day_str(&self) -> String { - let date_str = self.to_date_str(); - let day_str = date_str - .split_at_checked(10) - .unwrap() - .0; - String::from(day_str) - } - - /// Converts to a date string in ISO format, in UTC - /// Example: 10.30am 24 Oct 2024 UTC -> "2024-10-24T10:30:00.000Z" - pub fn to_date_str(&self) -> String { - self.chrono_datetime_utc.to_rfc3339() - } - - - fn is_day_str(str: &str) -> bool { - if str.len() != 10 { - return false; - } - for (ix, ch) in str.chars().enumerate() { - if ix == 4 || ix == 7 { - if ch != '-' { - return false; - } - } else { - if ch < '0' || ch > '9' { - return false; - } - } - } - return true; - } -} - -impl ToSql<Text, Sqlite> for DateTimeUtc { - fn to_sql<'b>( - &'b self, - out: &mut diesel::serialize::Output<'b, '_, Sqlite>, - ) -> serialize::Result { - out.set_value(self.to_date_str()); - Ok(serialize::IsNull::No) - } -} - -impl FromSql<Text, Sqlite> for DateTimeUtc { - fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<DateTimeUtc> { - let str = <String as FromSql<Text, Sqlite>>::from_sql(bytes)?; - Ok(Self::from_date_str(&str)?) - } -} - -#[cfg(test)] -mod test { - use chrono::TimeZone; - - use super::*; - - #[test] - fn given_midnight_when_day_diff_next_midnight_less_1s_then_return_0() { - let start = DateTimeUtc::new(&Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap().to_utc()); - let end = DateTimeUtc::new( - &Utc.with_ymd_and_hms(2000, 1, 1, 23, 59, 59) - .unwrap() - .to_utc(), - ); - - let day_diff = start.day_diff(&end); - let neg_day_diff = end.day_diff(&start); - - assert_eq!(day_diff, 0); - assert_eq!(day_diff, neg_day_diff); - } - - #[test] - fn given_midnight_when_day_diff_next_midnight_then_return_1() { - let start = DateTimeUtc::new(&Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap().to_utc()); - let end = DateTimeUtc::new(&Utc.with_ymd_and_hms(2000, 1, 2, 0, 0, 0).unwrap().to_utc()); - - let day_diff = start.day_diff(&end); - let neg_day_diff = end.day_diff(&start); - - assert_eq!(day_diff, 1); - assert_eq!(day_diff, neg_day_diff); - } - - #[test] - fn given_midnight_less_1s_when_day_diff_midnight_then_return_1() { - let start = DateTimeUtc::new( - &Utc.with_ymd_and_hms(2000, 1, 1, 23, 59, 59) - .unwrap() - .to_utc(), - ); - let end = DateTimeUtc::new(&Utc.with_ymd_and_hms(2000, 1, 2, 0, 0, 0).unwrap().to_utc()); - - let day_diff = start.day_diff(&end); - let neg_day_diff = end.day_diff(&start); - - assert_eq!(day_diff, 1); - assert_eq!(day_diff, neg_day_diff); - } - - #[test] - fn given_23_nov_1970_when_to_day_str_then_return_iso_day_str() { - let date_time_utc = DateTimeUtc::new( - &Utc.with_ymd_and_hms(1970, 11, 23, 0, 0, 0) - .unwrap() - .to_utc(), - ); - - assert_eq!(date_time_utc.to_day_str(), "1970-11-23"); - } -} |
