use crate::error::{Error, Result};
use chrono::{DateTime, NaiveDate, NaiveDateTime, TimeZone, Utc};
pub fn date_to_unix_nanos(date_str: &str) -> Result<i64> {
let naive_datetime = if date_str.len() == 10 {
match NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
Ok(naive_date) => naive_date.and_hms_opt(0, 0, 0).unwrap(), Err(_) => {
return Err(Error::InvalidDateFormat(format!(
"Invalid date format '{}'. Expected format: YYYY-MM-DD",
date_str
)));
}
}
} else {
match NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S") {
Ok(datetime) => datetime,
Err(_) => {
return Err(Error::InvalidDateFormat(format!(
"Invalid datetime format '{}'. Expected format: YYYY-MM-DD HH:MM:SS",
date_str
)));
}
}
};
let datetime_utc: DateTime<Utc> = DateTime::from_naive_utc_and_offset(naive_datetime, Utc);
let unix_nanos = datetime_utc.timestamp_nanos_opt().unwrap();
Ok(unix_nanos)
}
pub fn unix_nanos_to_date(unix_nanos: i64) -> Result<String> {
let datetime_utc: DateTime<Utc> = Utc.timestamp_nanos(unix_nanos);
let formatted_date = datetime_utc.format("%Y-%m-%d %H:%M:%S").to_string();
Ok(formatted_date)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_datetime_to_unix_nanos() -> Result<()> {
let date_str = "2021-11-01 01:01:01";
let unix_nanos = date_to_unix_nanos(date_str)?;
assert_eq!(1635728461000000000, unix_nanos);
Ok(())
}
#[test]
fn test_date_to_unix_nanos() -> Result<()> {
let date_str = "2021-11-01";
let unix_nanos = date_to_unix_nanos(date_str)?;
assert_eq!(1635724800000000000, unix_nanos);
Ok(())
}
#[test]
fn test_unix_to_date() -> Result<()> {
let unix = 1635728461000000000;
let iso = unix_nanos_to_date(unix)?;
assert_eq!("2021-11-01 01:01:01", iso);
Ok(())
}
}