#
mcaptcha/
date.rs

    1// Copyright (C) 2022  Aravinth Manivannan <realaravinth@batsense.net>
    2// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
    3//
    4// SPDX-License-Identifier: AGPL-3.0-or-later
    5
    6use std::fmt::Debug;
    7
    8use sqlx::types::time::OffsetDateTime;
    9
    10#[derive(Clone)]
    11pub struct Date {
    12    pub time: OffsetDateTime,
    13}
    14
    15impl Debug for Date {
    16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    17        f.debug_struct("Date")
    18            .field("time", &self.print_date())
    19            .finish()
    20    }
    21}
    22
    23pub const MINUTE: i64 = 60;
    24pub const HOUR: i64 = MINUTE * 60;
    25pub const DAY: i64 = HOUR * 24;
    26pub const WEEK: i64 = DAY * 7;
    27
    28impl Date {
    29    pub fn format(date: &OffsetDateTime) -> String {
    30        let timestamp = date.unix_timestamp();
    31        let now = OffsetDateTime::now_utc().unix_timestamp();
    32
    33        let difference = now - timestamp;
    34
    35        if difference >= 3 * WEEK {
    36            format!("{}{}{}", date.year(), date.month(), date.date())
    37        } else if (DAY..(3 * WEEK)).contains(&difference) {
    38            format!("{} days ago", date.hour())
    39        } else if (HOUR..DAY).contains(&difference) {
    40            format!("{} hours ago", date.hour())
    41        } else if (MINUTE..HOUR).contains(&difference) {
    42            format!("{} minutes ago", date.minute())
    43        } else {
    44            format!("{} seconds ago", date.second())
    45        }
    46    }
    47
    48    /// print relative time from date
    49    pub fn print_date(&self) -> String {
    50        Self::format(&self.time)
    51    }
    52
    53    /// print date
    54    pub fn date(&self) -> String {
    55        format!(
    56            "{}{}{}",
    57            self.time.year(),
    58            self.time.month(),
    59            self.time.date()
    60        )
    61    }
    62
    63    pub fn new(unix: i64) -> Self {
    64        Self {
    65            time: OffsetDateTime::from_unix_timestamp(unix).unwrap(),
    66        }
    67    }
    68}
    69
    70#[cfg(test)]
    71mod tests {
    72    use super::*;
    73
    74    #[test]
    75    fn print_date_test() {
    76        let mut n = Date {
    77            time: OffsetDateTime::now_utc(),
    78        };
    79
    80        let timestamp = n.time.unix_timestamp();
    81        println!("timestamp: {}", timestamp);
    82
    83        // seconds test
    84        assert!(n.print_date().contains("seconds ago"));
    85        n.time = OffsetDateTime::from_unix_timestamp(timestamp - 5).unwrap();
    86        assert!(n.print_date().contains("seconds ago"));
    87
    88        // minutes test
    89        n.time = OffsetDateTime::from_unix_timestamp(timestamp - MINUTE * 2).unwrap();
    90        assert!(n.print_date().contains("minutes ago"));
    91        n.time = OffsetDateTime::from_unix_timestamp(timestamp - MINUTE * 56).unwrap();
    92        assert!(n.print_date().contains("minutes ago"));
    93
    94        // hours test
    95        n.time = OffsetDateTime::from_unix_timestamp(timestamp - HOUR).unwrap();
    96        assert!(n.print_date().contains("hours ago"));
    97        n.time = OffsetDateTime::from_unix_timestamp(timestamp - HOUR * 23).unwrap();
    98        assert!(n.print_date().contains("hours ago"));
    99
    100        // days test
    101        n.time = OffsetDateTime::from_unix_timestamp(timestamp - 2 * WEEK).unwrap();
    102        assert!(n.print_date().contains("days ago"));
    103
    104        // date test
    105        n.time = OffsetDateTime::from_unix_timestamp(timestamp - 6 * WEEK).unwrap();
    106        let date = format!("{}{}{}", n.time.year(), n.time.month(), n.time.date());
    107        assert!(n.print_date().contains(&date))
    108    }
    109}