1use crate::error::{Error, Result};
2use chrono::{DateTime, NaiveDate, NaiveDateTime, TimeZone, Utc};
3
4pub fn date_to_unix_nanos(date_str: &str) -> Result<i64> {
5 let naive_datetime = if date_str.len() == 10 {
6 match NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
8 Ok(naive_date) => naive_date.and_hms_opt(0, 0, 0).unwrap(), Err(_) => {
10 return Err(Error::InvalidDateFormat(format!(
11 "Invalid date format '{}'. Expected format: YYYY-MM-DD",
12 date_str
13 )));
14 }
15 }
16 } else {
17 match NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S") {
19 Ok(datetime) => datetime,
20 Err(_) => {
21 return Err(Error::InvalidDateFormat(format!(
22 "Invalid datetime format '{}'. Expected format: YYYY-MM-DD HH:MM:SS",
23 date_str
24 )));
25 }
26 }
27 };
28
29 let datetime_utc: DateTime<Utc> = DateTime::from_naive_utc_and_offset(naive_datetime, Utc);
31
32 let unix_nanos = datetime_utc.timestamp_nanos_opt().unwrap();
34
35 Ok(unix_nanos)
36}
37
38pub fn unix_nanos_to_date(unix_nanos: i64) -> Result<String> {
39 let datetime_utc: DateTime<Utc> = Utc.timestamp_nanos(unix_nanos);
41
42 let formatted_date = datetime_utc.format("%Y-%m-%d %H:%M:%S").to_string();
44
45 Ok(formatted_date)
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_datetime_to_unix_nanos() -> Result<()> {
54 let date_str = "2021-11-01 01:01:01";
55
56 let unix_nanos = date_to_unix_nanos(date_str)?;
58
59 assert_eq!(1635728461000000000, unix_nanos);
61 Ok(())
62 }
63
64 #[test]
65 fn test_date_to_unix_nanos() -> Result<()> {
66 let date_str = "2021-11-01";
67
68 let unix_nanos = date_to_unix_nanos(date_str)?;
70
71 assert_eq!(1635724800000000000, unix_nanos);
73
74 Ok(())
75 }
76
77 #[test]
78 fn test_unix_to_date() -> Result<()> {
79 let unix = 1635728461000000000;
80
81 let iso = unix_nanos_to_date(unix)?;
83
84 assert_eq!("2021-11-01 01:01:01", iso);
86 Ok(())
87 }
88}