zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
use chrono::offset::Offset;
use chrono::{DateTime, NaiveDateTime, TimeZone, Utc};
use chrono_tz::Tz;

pub use crate::core::error2::Error;
pub use crate::core::error2::Result;

const DATE_TIME_FORMAT_UTC: &str = "%Y-%m-%dT%H:%M:%S.%3fZ";

pub fn get_date_offsets() -> String {
    let c = chrono::Local::now().offset().fix().local_minus_utc() / 3600;

    if c >= 0 {
        format!("+{:02}", c)
    } else {
        format!("-{:02}", c)
    }
}

pub fn now() -> DateTime<Utc> {
    chrono::Utc::now()
}

pub fn curr_date() -> String {
    chrono::Utc::now().format("%Y%m%d").to_string()
}

pub fn date_string() -> String {
    chrono::Local::now()
        .format("%Y-%m-%dT%H:%M:%S.%3f%Z")
        .to_string()
}

pub fn format_date(format: &str) -> String {
    let s = chrono::Local::now().format(format).to_string();

    if !s.ends_with("+00:00") {
        return s;
    }

    let mut out = String::with_capacity(s.len() - 6 + 1);
    out.push_str(&s[..s.len() - 6]);
    out.push('Z');

    out
}

pub fn timestamp_millis() -> i64 {
    chrono::Utc::now().timestamp_millis()
}

pub fn parse_utc_datetime_str(datetime_str: &str) -> Result<DateTime<Utc>> {
    let naive_date_time = NaiveDateTime::parse_from_str(datetime_str, DATE_TIME_FORMAT_UTC)
        .map_err(|e| Error::throw("", Some(e)))?;

    Ok(DateTime::<Utc>::from_naive_utc_and_offset(
        naive_date_time,
        Utc,
    ))
}

pub fn parse_utc_string_to_millis(datetime_str: &str) -> Result<u64> {
    let naive_date_time = NaiveDateTime::parse_from_str(datetime_str, DATE_TIME_FORMAT_UTC)
        .map_err(|e| Error::throw("", Some(e)))?;

    Ok(DateTime::<Utc>::from_naive_utc_and_offset(naive_date_time, Utc).timestamp_millis() as u64)
}

pub fn to_utc_datetime_str(datetime: &DateTime<Utc>) -> String {
    datetime.format(DATE_TIME_FORMAT_UTC).to_string()
}

pub fn to_utc_datetime_string(timestamp: i64) -> String {
    to_utc_datetime_str(&to_utc_datetime(timestamp))
}

pub fn to_utc_datetime(timestamp: i64) -> DateTime<Utc> {
    let naive = DateTime::from_timestamp_millis(timestamp).unwrap();
    chrono::Utc.from_utc_datetime(&naive.naive_utc())
}

// 获取系统时区
// let tz = system::get_timezone().unwrap();
// println!("当前 tz: {}", tz.name()); // 例: "Asia/Shanghai"
// let tz: Tz = "Asia/Shanghai".parse();
pub fn parse_datestr_to_date(date_str: &str, format: &str, tz_name: &str) -> chrono::DateTime<Utc> {
    let tz: Tz = tz_name.parse().unwrap();

    // 先解析成本地 NaiveDateTime
    let naive = NaiveDateTime::parse_from_str(date_str, format).unwrap();

    // 绑定时区,得到 DateTime<FixedOffset>
    let local_dt = tz.from_local_datetime(&naive).unwrap();

    // 转换为 UTC
    local_dt.with_timezone(&Utc)
}

pub fn timestamp_text_line(timestamp: i64) -> String {
    let now = timestamp_millis();

    if (now - timestamp) > 1000 * 3600 * 24 * 4 {
        "四天前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 24 * 3 {
        "三天前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 24 * 2 {
        "二天前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 24 {
        "一天前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 22 {
        "二十二小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 20 {
        "二十小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 18 {
        "十八小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 16 {
        "十六小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 14 {
        "十四小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 12 {
        "十二小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 6 {
        "六小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 3 {
        "三小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 * 2 {
        "两小时以前".to_string()
    } else if (now - timestamp) > 1000 * 3600 {
        "一小时以前".to_string()
    } else if (now - timestamp) > 1000 * 60 * 10 {
        "十分钟以前".to_string()
    } else if (now - timestamp) > 1000 * 60 * 5 {
        "五分钟以前".to_string()
    } else if (now - timestamp) > 1000 * 60 {
        "一分钟以前".to_string()
    } else if (now - timestamp) > 1000 * 30 {
        "30秒以前".to_string()
    } else {
        "刚刚".to_string()
    }
}