1use std::sync::atomic::{AtomicU64, Ordering};
2
3use chrono::offset::Utc;
4
5static DELAYED_SEC: AtomicU64 = AtomicU64::new(0);
6
7#[inline]
8pub fn timestamp() -> u64 {
9 Utc::now().timestamp() as u64
10}
11
12#[inline]
13pub fn timestamp_subsec_nanos() -> (u64, u32) {
14 let dt = Utc::now();
15 (dt.timestamp() as u64, dt.timestamp_subsec_nanos())
16}
17
18pub struct DelayedTime();
21
22impl DelayedTime {
23 #[inline(always)]
27 pub fn start() -> u64 {
28 let now = timestamp();
29 match DELAYED_SEC.compare_exchange(0, now, Ordering::SeqCst, Ordering::Acquire) {
30 Ok(_) => {
31 std::thread::spawn(|| {
32 let d = std::time::Duration::from_secs(1);
33 loop {
34 DELAYED_SEC.store(timestamp(), Ordering::Release);
35 std::thread::sleep(d);
36 }
37 });
38 now
39 }
40 Err(_now) => _now,
41 }
42 }
43
44 #[inline(always)]
46 pub fn now() -> u64 {
47 let now = DELAYED_SEC.load(Ordering::Acquire);
48 if now == 0 { Self::start() } else { now }
49 }
50
51 #[inline(always)]
53 pub fn get() -> u64 {
54 let now = DELAYED_SEC.load(Ordering::Acquire);
55 if now == 0 { timestamp() } else { now }
56 }
57}
58
59#[inline]
65pub fn check_timelapse(pre_ts: u64, duration: u64) -> bool {
66 let now = DelayedTime::get();
67 if now <= pre_ts {
68 return false;
69 }
70 now - pre_ts >= duration
71}