agentsight_capture_core/
time.rs1use std::sync::OnceLock;
10use std::time::{SystemTime, UNIX_EPOCH};
11
12static BOOT_TIME_SECS: OnceLock<i64> = OnceLock::new();
14
15pub fn get_boot_time_secs() -> i64 {
19 *BOOT_TIME_SECS.get_or_init(|| {
20 if let Ok(boot_time) = i64::try_from(sysinfo::System::boot_time())
21 && boot_time > 0
22 {
23 return boot_time;
24 }
25
26 let now_secs = SystemTime::now()
27 .duration_since(UNIX_EPOCH)
28 .unwrap()
29 .as_secs() as i64;
30 let uptime_secs = i64::try_from(sysinfo::System::uptime())
31 .ok()
32 .filter(|uptime| *uptime > 0)
33 .unwrap_or(1);
34 now_secs.saturating_sub(uptime_secs)
35 })
36}
37
38pub fn boot_ns_to_epoch_ms(ns_since_boot: u64) -> u64 {
48 let boot_time_secs = get_boot_time_secs();
49 let boot_time_ms = boot_time_secs * 1000;
50 let offset_ms = (ns_since_boot / 1_000_000) as i64;
51 (boot_time_ms + offset_ms) as u64
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_boot_time_is_reasonable() {
60 let boot_time = get_boot_time_secs();
61 let now = SystemTime::now()
63 .duration_since(UNIX_EPOCH)
64 .unwrap()
65 .as_secs() as i64;
66 assert!(boot_time < now);
67 assert!(boot_time > 1577836800); }
70
71 #[test]
72 fn test_boot_ns_to_epoch_ms_conversion() {
73 let ns_since_boot = 1_000_000_000_000u64; let result_ms = boot_ns_to_epoch_ms(ns_since_boot);
76
77 let boot_time = get_boot_time_secs();
78 let expected_ms = (boot_time + 1000) * 1000;
79
80 assert_eq!(result_ms, expected_ms as u64);
81 }
82}