x-common-lib 0.1.8

DXMesh rust dxc develop library
Documentation
use time::OffsetDateTime;

use crate::base::status::Status;

const SECONDS_OF_DAY: i64 = 60 * 60 * 24;

const MILL_SECONDS_OF_DAY: i64 = SECONDS_OF_DAY * 1000;

const EIGHT_HOUR: i64 = 60 * 60 * 8 * 1000;

/**

 * 获取下一天刚开始的时间戳
 */
#[allow(dead_code)]
pub fn cur_timestamp() -> i64 {
    (OffsetDateTime::now_utc().unix_timestamp_nanos() / 1_000_000) as i64
}

/**

 * 获取下一天刚开始的时间戳
 */
#[allow(dead_code)]
pub fn next_day_begin_timestamp_from_today() -> i64 {
    next_day_begin_timestamp_from(cur_timestamp())
}

/**

 * 获取下一天刚开始的时间戳
 */
#[allow(dead_code)]
pub fn next_day_begin_timestamp_from(timestamp: i64) -> i64 {
    let next_day =
        ((timestamp + EIGHT_HOUR) / MILL_SECONDS_OF_DAY + 1) * MILL_SECONDS_OF_DAY - EIGHT_HOUR;
    next_day
}

/**

 *  获取前一天的时间
 */
#[allow(dead_code)]
pub fn pre_day_begin_timestamp_from_today() -> i64 {
    pre_day_begin_timestamp_from(cur_timestamp())
}

/**

 *  获取前一天的时间
 */
#[allow(dead_code)]
pub fn pre_day_begin_timestamp_from(timestamp: i64) -> i64 {
    let pre_day =
        (timestamp / MILL_SECONDS_OF_DAY) * MILL_SECONDS_OF_DAY - MILL_SECONDS_OF_DAY - EIGHT_HOUR;
    pre_day
}

/**

 *  获取指定时间的开始时间
 */
#[allow(dead_code)]
pub fn begin_timestamp_from(timestamp: i64) -> i64 {
    (timestamp / MILL_SECONDS_OF_DAY) * MILL_SECONDS_OF_DAY * MILL_SECONDS_OF_DAY - EIGHT_HOUR
}

/**

 * 获取指定时间戳,在当天最后这一分钟的时间戳
 */
#[allow(dead_code)]
pub fn last_min_timestamp_from(timestamp: i64) -> i64 {
    let day_begin_timestamp = begin_timestamp_from(timestamp);
    day_begin_timestamp + MILL_SECONDS_OF_DAY - 60 * 1000
}

#[allow(dead_code)]
fn timestamp_to_local(timestamp: i64) -> i64 {
    let local_offset = OffsetDateTime::now_local();

    if let Ok(local) = local_offset {
        return timestamp + (local.offset().whole_seconds() as i64 * 1000);
    }
    return timestamp;
}

/**

 * 通过时间戳获取年月日
 */
#[allow(dead_code)]
pub fn ymd_from_timestamp(timestamp: i64) -> Result<(u32, u32, u32), Status> {
    let local_timestamp = timestamp_to_local(timestamp);
    let datetime = OffsetDateTime::from_unix_timestamp(local_timestamp / 1000);
    if let Ok(date) = datetime {
        Ok((date.year() as u32, date.month() as u32, date.day() as u32))
    } else {
        Err(Status::error("转换为 datetime 错误!".into()))
    }
}
/**

 * 通过时间戳获取时分秒
 */
#[allow(dead_code)]
pub fn hms_from_timestamp(timestamp: i64) -> Result<(u32, u32, u32), Status> {
    let local_timestamp = timestamp_to_local(timestamp);
    let datetime = OffsetDateTime::from_unix_timestamp(local_timestamp / 1000);
    if let Ok(date) = datetime {
        Ok((
            date.hour() as u32,
            date.minute() as u32,
            date.second() as u32,
        ))
    } else {
        Err(Status::error("转换为 datetime 错误!".into()))
    }
}

fn fill_buffer(
    format: &str,
    match_char: char,
    time_no: i32,
    buffer: &mut [u8],
    cur_index: &mut usize,
) {
    let mut symbol_num = 0;
    // 获取字符个数
    while *cur_index < format.len() {
        let ch = format.chars().nth(*cur_index).unwrap();
        if ch == match_char {
            symbol_num += 1;
        } else {
            *cur_index -= 1;
            break;
        }
        *cur_index += 1;
    }
    if *cur_index == format.len() {
        *cur_index -= 1;
    }
    let mut begin = 1;
    for j in 0..symbol_num {
        buffer[*cur_index - j] = (time_no / begin % 10) as u8 + 48;
        begin *= 10;
    }
}
#[allow(dead_code)]
pub fn time_to_str(
    format: &str,
    year: i32,
    month: i32,
    day: i32,
    hour: i32,
    minutes: i32,
    seconds: i32,
    millisecond: i32,
) -> String {
    let format_chars: Vec<char> = format.chars().collect();
    let mut buffer: Vec<u8> = vec![0; format_chars.len()];
    let format_len = format.len();
    let mut cur_index = 0;
    while cur_index < format_len {
        let ch = format_chars[cur_index];
        match ch {
            'y' => fill_buffer(format, ch, year, &mut buffer, &mut cur_index),
            'M' => fill_buffer(format, ch, month, &mut buffer, &mut cur_index),
            'd' => fill_buffer(format, ch, day, &mut buffer, &mut cur_index),
            'h' => fill_buffer(format, ch, hour, &mut buffer, &mut cur_index),
            'm' => fill_buffer(format, ch, minutes, &mut buffer, &mut cur_index),
            's' => fill_buffer(format, ch, seconds, &mut buffer, &mut cur_index),
            'S' => fill_buffer(format, ch, millisecond, &mut buffer, &mut cur_index),
            _ => buffer[cur_index] = ch as u8,
        }
        cur_index += 1;
    }
    unsafe { String::from_utf8_unchecked(buffer) }
}
#[allow(dead_code)]
pub fn timestamp_to_string(format: &str, timestamp: i64) -> String {
    let local_timestamp = timestamp_to_local(timestamp);
    let datetime = OffsetDateTime::from_unix_timestamp(local_timestamp / 1000);
    if let Ok(date) = datetime {
        let second_timestamp = local_timestamp / 1000;
        let millisecond = (local_timestamp - second_timestamp * 1000) as i32;
        time_to_str(
            format,
            date.year(),
            date.month() as i32,
            date.day() as i32,
            date.hour() as i32,
            date.minute() as i32,
            date.second() as i32,
            millisecond,
        )
    } else {
        "--".to_string()
    }
}

#[allow(dead_code)]
pub fn cur_time_str_with_format(format: &str) -> String {
  timestamp_to_string(format, cur_timestamp())
}



/**

 *  获取当前时间
 */
#[allow(dead_code)]
pub fn cur_time_str() -> String {
  cur_time_str_with_format("yyyy-MM-dd hh:mm:ss.SSS")
}


fn buffer_to_number(
    format: &str,
    str: &str,
    match_char: char,
    format_len: usize,
    time_no: &mut i32,
    cur_index: &mut usize,
) {
    let mut ch: char;
    let mut c_ch: char;
    *time_no = 0;
    let mut has_val = false;

    while *cur_index < format_len {
        ch = format.chars().nth(*cur_index).unwrap();
        c_ch = str.chars().nth(*cur_index).unwrap();
        if ch != match_char || !c_ch.is_ascii_digit() {
            if has_val {
                *cur_index -= 1;
            }
            break;
        }
        has_val = true;
        *time_no *= 10;
        *time_no += c_ch as i32 - '0' as i32;
        *cur_index += 1;
    }
}

pub fn str_to_time(format: &str, string: &str) -> Option<(i32, i32, i32, i32, i32, i32, i32)> {
    let mut year = 0;
    let mut month = 0;
    let mut day = 0;
    let mut hour = 0;
    let mut minutes = 0;
    let mut seconds = 0;
    let mut millisecond = 0;

    let format_len = format.len();
    let str_len = string.len();
    if str_len < format_len {
        return None;
    }

    let mut cur_index = 0;

    while cur_index < format_len {
        let ch = format.chars().nth(cur_index).unwrap();
        match ch {
            'y' => buffer_to_number(format, string, ch, format_len, &mut year, &mut cur_index),
            'M' => buffer_to_number(format, string, ch, format_len, &mut month, &mut cur_index),
            'd' => buffer_to_number(format, string, ch, format_len, &mut day, &mut cur_index),
            'h' => buffer_to_number(format, string, ch, format_len, &mut hour, &mut cur_index),
            'm' => buffer_to_number(format, string, ch, format_len, &mut minutes, &mut cur_index),
            's' => buffer_to_number(format, string, ch, format_len, &mut seconds, &mut cur_index),
            'S' => buffer_to_number(
                format,
                string,
                ch,
                format_len,
                &mut millisecond,
                &mut cur_index,
            ),
            _ => {
                if ch != string.chars().nth(cur_index).unwrap() {
                    return None;
                }
            }
        }
        cur_index += 1;
    }

    Some((year, month, day, hour, minutes, seconds, millisecond))
}