use chrono::{DateTime, NaiveDate, NaiveDateTime, TimeZone, Utc};
#[inline]
pub fn f64_to_i64(f: f64) -> Option<i64> {
if !f.is_finite() {
return None;
}
let truncated = f.trunc();
if truncated < i64::MIN as f64 || truncated > i64::MAX as f64 {
return None;
}
Some(truncated as i64)
}
#[inline]
pub fn parse_string_as_bool(s: &str) -> Option<bool> {
match s.to_ascii_lowercase().trim() {
"t" | "tr" | "tru" | "true" | "y" | "ye" | "yes" | "on" | "1" => Some(true),
"f" | "fa" | "fal" | "fals" | "false" | "n" | "no" | "of" | "off" | "0" => Some(false),
_ => None,
}
}
#[inline]
pub fn parse_timestamp_to_utc(s: &str) -> Option<DateTime<Utc>> {
if let Ok(dt) = DateTime::parse_from_rfc3339(s) {
return Some(dt.with_timezone(&Utc));
}
for fmt in &["%Y-%m-%d %H:%M:%S%z", "%Y-%m-%dT%H:%M:%S%z"] {
if let Ok(dt) = DateTime::parse_from_str(s, fmt) {
return Some(dt.with_timezone(&Utc));
}
}
for fmt in &[
"%Y-%m-%d %H:%M:%S",
"%Y-%m-%dT%H:%M:%S",
"%Y-%m-%d %H:%M:%S%.f",
"%Y-%m-%dT%H:%M:%S%.f",
"%Y/%m/%d %H:%M:%S",
] {
if let Ok(naive) = NaiveDateTime::parse_from_str(s, fmt) {
return Some(Utc.from_utc_datetime(&naive));
}
}
for fmt in &["%Y-%m-%d", "%Y/%m/%d"] {
if let Ok(date) = NaiveDate::parse_from_str(s, fmt) {
if let Some(naive) = date.and_hms_opt(0, 0, 0) {
return Some(Utc.from_utc_datetime(&naive));
}
}
}
None
}