use crate::use_m::*;
use chrono::{DateTime, Duration, NaiveDate, NaiveDateTime, Utc};
use python_comm_macros::auto_func_name;
use std::time;
#[inline]
pub fn bj_date() -> NaiveDate {
bj_time().date()
}
#[inline]
pub fn bj_dates() -> String {
bj_date().format("%Y-%m-%d").to_string()
}
#[inline]
pub fn bj_time() -> NaiveDateTime {
(Utc::now() + Duration::hours(8)).naive_utc()
}
#[inline]
pub fn bj_times() -> String {
bj_time().format("%Y-%m-%d %H:%M:%S").to_string()
}
#[inline]
pub fn bj_timestamp() -> i64 {
Utc::now().timestamp()
}
#[inline]
pub fn bj_timestamp_millis() -> i64 {
Utc::now().timestamp_millis()
}
#[inline]
pub fn bjtc_df(date: &NaiveDate) -> f64 {
bjtc_dn(date) as f64
}
#[inline]
pub fn bjtc_dn(date: &NaiveDate) -> i64 {
bjtc_tn(&bjtc_dt(date))
}
#[inline]
pub fn bjtc_ds(date: &NaiveDate) -> String {
date.format("%Y-%m-%d").to_string()
}
#[inline]
pub fn bjtc_dt(date: &NaiveDate) -> NaiveDateTime {
date.and_hms(0, 0, 0)
}
#[inline]
#[auto_func_name]
pub fn bjtc_fd(timestamp: f64) -> Result<NaiveDate, MoreError> {
bjtc_nd(
timestamp as i64,
((timestamp - (timestamp as i64 as f64)) * 1000.0) as u32,
)
.m(m!(__func__, &format!("timestamp={}", timestamp)))
}
#[inline]
#[auto_func_name]
pub fn bjtc_fs(timestamp: f64) -> Result<String, MoreError> {
Ok(bjtc_ts(
&bjtc_ft(timestamp).m(m!(__func__, &format!("timestamp={}", timestamp)))?,
))
}
#[inline]
#[auto_func_name]
pub fn bjtc_ft(timestamp: f64) -> Result<NaiveDateTime, MoreError> {
bjtc_nt(
timestamp as i64,
((timestamp - (timestamp as i64 as f64)) * 1000.0) as u32,
)
.m(m!(__func__, &format!("timestamp={}", timestamp)))
}
#[inline]
#[auto_func_name]
pub fn bjtc_nd(timestamp: i64, millis: u32) -> Result<NaiveDate, MoreError> {
Ok(bjtc_td(
&bjtc_nt(timestamp, millis).m(m!(__func__, &format!("timestamp={}", timestamp)))?,
))
}
#[inline]
#[auto_func_name]
pub fn bjtc_ns(timestamp: i64, millis: u32) -> Result<String, MoreError> {
Ok(bjtc_ts(
&bjtc_nt(timestamp, millis).m(m!(__func__, &format!("timestamp={}", timestamp)))?,
))
}
#[inline]
#[auto_func_name]
pub fn bjtc_nt(timestamp: i64, millis: u32) -> Result<NaiveDateTime, MoreError> {
NaiveDateTime::from_timestamp_opt(timestamp, millis * 1000000).ok_or(m!(
__func__,
&format!("invalid timestamp={}", timestamp),
"more"
))
}
#[inline]
#[auto_func_name]
pub fn bjtc_sd(text: &String) -> Result<NaiveDate, MoreError> {
NaiveDate::parse_from_str(text, "%Y-%m-%d").m(m!(__func__, text))
}
#[inline]
#[auto_func_name]
pub fn bjtc_st(text: &String) -> Result<NaiveDateTime, MoreError> {
NaiveDateTime::parse_from_str(text, "%Y-%m-%d %H:%M:%S").m(m!(__func__, text))
}
#[inline]
pub fn bjtc_td(time: &NaiveDateTime) -> NaiveDate {
time.date()
}
#[inline]
pub fn bjtc_tf(time: &NaiveDateTime) -> f64 {
bjtc_tn(time) as f64
}
#[inline]
pub fn bjtc_tn(time: &NaiveDateTime) -> i64 {
time.timestamp()
}
#[inline]
pub fn bjtc_ts(time: &NaiveDateTime) -> String {
time.format("%Y-%m-%d %H:%M:%S").to_string()
}
pub fn bjtc_from_duration(anchor: &DateTime<Utc>, millis: f64) -> i64 {
(*anchor + chrono::Duration::milliseconds(millis as i64)).timestamp_millis()
}
#[auto_func_name]
pub fn bjtc_to_duration(anchor: &DateTime<Utc>, timestamp_millis: i64) -> Result<time::Duration, MoreError> {
let elapsed = bjtc_nt(timestamp_millis / 1000, (timestamp_millis % 1000) as u32)
.m(m!(__func__, &format!("timestamp={}", timestamp_millis)))?
- anchor.naive_utc();
if elapsed.num_milliseconds() >= 0 {
Ok(time::Duration::from_millis(elapsed.num_milliseconds() as u64))
} else {
m!(
__func__,
&format!("{} 结果为负值 {}", timestamp_millis, elapsed.num_seconds()),
"result"
)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::thread;
#[test]
fn test_bjtc_from_to_duration() {
let anchor = Utc::now();
let now = time::Instant::now();
thread::sleep(time::Duration::from_millis(700)); let elapsed = now.elapsed().as_secs_f64();
let t1 = bjtc_from_duration(&anchor, elapsed * 1000.0);
let t2 = bjtc_to_duration(&anchor, t1).unwrap();
let diff = t2.as_secs_f64() - elapsed;
assert!(diff > -0.01 && diff < 0.01);
let t1 = bjtc_from_duration(&anchor, 1000.0);
let t3 = bjtc_to_duration(&anchor, t1 - 1000);
assert_eq!(t3.is_err(), false);
assert_eq!(t3.unwrap().as_secs_f64(), 0.0);
let t4 = bjtc_to_duration(&anchor, t1 - 1001);
assert_eq!(t4.is_err(), true);
let diff = bjtc_to_duration(&anchor, bj_timestamp_millis()).unwrap().as_secs_f64() - 0.7;
assert!(diff > -0.1 && diff < 0.1);
}
}