use bt_logger::get_error;
use chrono::Local;
use time::macros::format_description;
use time::{OffsetDateTime, PrimitiveDateTime, UtcOffset};
use time::format_description::well_known::Iso8601;
use time_tz::{OffsetDateTimeExt, PrimitiveDateTimeExt, Tz, timezones};
pub fn get_current_time_and_date() -> (String, String) {
get_formatted_time_and_date("%H:%M", "%B %d, %Y")
}
pub fn get_formatted_time_and_date(time_format: &str, date_format: &str) -> (String, String) {
let now = Local::now();
let time = now.format(&time_format).to_string();
let date = now.format(&date_format).to_string();
(time, date)
}
pub fn get_formatted_date(date_format: &str) -> String {
Local::now().format(&date_format).to_string()
}
pub fn parse_local_to_utc(
datetime_str: &str,
tz_name: &str,
) -> Result<PrimitiveDateTime, Box<dyn std::error::Error>> {
let naive = PrimitiveDateTime::parse(datetime_str, &Iso8601::PARSING)?;
let tz: &Tz = timezones::get_by_name(tz_name).ok_or_else(|| get_error!("parse_local_to_utc","Unknown timezone: {}", tz_name))?;
let zoned = match naive.assume_timezone(tz){
time_tz::OffsetResult::Some(z) => z,
time_tz::OffsetResult::Ambiguous(z0, z1) => return Err(get_error!("parse_local_to_utc", "Ambigous time {}. May get {} or {}.",datetime_str, z0, z1 ).into()),
time_tz::OffsetResult::None => return Err(get_error!("parse_local_to_utc", "cannot parse string to PrimitiveDateTime with TimeZone").into()),
};
let utc = zoned.to_offset(UtcOffset::UTC);
Ok(PrimitiveDateTime::new(utc.date(), utc.time()))
}
pub fn format_in_utcoffset_timezone(
utc_dt: PrimitiveDateTime,
tz_offset: UtcOffset,
) -> String {
let utc_dt: OffsetDateTime = utc_dt.assume_utc();
let local_dt = utc_dt.to_offset(tz_offset);
let format = format_description!("[year]-[month repr:short]-[day] [hour repr:12]:[minute] [period]");
local_dt.format(format).unwrap()
}
pub fn format_in_iana_timezone_or_utc(
utc_datetime: PrimitiveDateTime,
tz_name: &str,
) -> String {
let utc_dt = utc_datetime.assume_utc();
let tz = timezones::get_by_name(tz_name)
.unwrap_or(timezones::db::UTC);
let local_dt = utc_dt.to_timezone(tz);
let format = format_description!(
"[year]-[month repr:short]-[day] [hour repr:12]:[minute] [period]"
);
local_dt.format(&format).unwrap()
}