kensho/src/range.rs

44 lines
1.2 KiB
Rust

use anyhow::{bail, format_err, Result};
use chrono::{DateTime, Local, LocalResult, NaiveDate, TimeZone};
#[derive(Debug)]
pub(super) struct Range {
pub start: DateTime<Local>,
pub end: DateTime<Local>,
}
pub(super) fn try_create_range<S: AsRef<str>>(date: S) -> Result<Range> {
Ok(Range {
start: create_day_bound(&date, 0, 0, 0)?,
end: create_day_bound(date, 23, 59, 59)?,
})
}
fn create_day_bound<S: AsRef<str>>(
day: S,
hour: u32,
minute: u32,
second: u32,
) -> Result<DateTime<Local>> {
let ts: Vec<&str> = day.as_ref().split("-").collect();
if ts.len() != 3 {
bail!("Invalid date format! {}", day.as_ref())
}
let (year, month, day) = if let [year, month, day, ..] = &ts[..] {
(year, month, day)
} else {
bail!("Invalid date format! {}", day.as_ref())
};
let b = Local.from_local_datetime(
&NaiveDate::from_ymd_opt(year.parse()?, month.parse()?, day.parse()?)
.ok_or_else(|| format_err!("Invalid date!"))?
.and_hms_opt(hour, minute, second)
.ok_or_else(|| format_err!("Invalid time!"))?,
);
if let LocalResult::Single(b) = b {
Ok(b)
} else {
bail!("Cannot construct day boundary!")
}
}