use chrono::{DateTime, Local, NaiveDateTime, TimeZone};
use std::time::{SystemTime, UNIX_EPOCH};
pub fn now() -> DateTime<Local> {
Local::now()
}
pub fn format(dt: DateTime<Local>, fmt: &str) -> String {
dt.format(fmt).to_string()
}
pub fn parse(s: &str, fmt: &str) -> Result<DateTime<Local>, chrono::ParseError> {
let ndt = NaiveDateTime::parse_from_str(s, fmt)?;
Ok(Local.from_local_datetime(&ndt).unwrap())
}
pub fn timestamp_to_datetime(ts: i64) -> DateTime<Local> {
Local.timestamp_opt(ts, 0).unwrap()
}
pub fn datetime_to_timestamp(dt: DateTime<Local>) -> i64 {
dt.timestamp()
}
pub fn diff_in_seconds(dt1: DateTime<Local>, dt2: DateTime<Local>) -> i64 {
(dt1 - dt2).num_seconds()
}
pub fn current_timestamp() -> i64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_secs() as i64
}
pub fn is_leap_year(year: i32) -> bool {
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
}
pub fn days_in_month(year: i32, month: u32) -> u32 {
match month {
1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
4 | 6 | 9 | 11 => 30,
2 => {
if is_leap_year(year) {
29
} else {
28
}
}
_ => 0,
}
}
pub mod arithmetic {
use super::*;
use chrono::Duration;
pub fn add_days(dt: DateTime<Local>, days: i64) -> DateTime<Local> {
dt + Duration::days(days)
}
pub fn sub_days(dt: DateTime<Local>, days: i64) -> DateTime<Local> {
dt - Duration::days(days)
}
pub fn add_hours(dt: DateTime<Local>, hours: i64) -> DateTime<Local> {
dt + Duration::hours(hours)
}
pub fn sub_hours(dt: DateTime<Local>, hours: i64) -> DateTime<Local> {
dt - Duration::hours(hours)
}
pub fn add_minutes(dt: DateTime<Local>, minutes: i64) -> DateTime<Local> {
dt + Duration::minutes(minutes)
}
pub fn sub_minutes(dt: DateTime<Local>, minutes: i64) -> DateTime<Local> {
dt - Duration::minutes(minutes)
}
pub fn diff_in_days(dt1: DateTime<Local>, dt2: DateTime<Local>) -> i64 {
(dt1.date_naive() - dt2.date_naive()).num_days().abs()
}
}