windjammer_runtime/
time.rs1use chrono::{DateTime, Local, Utc};
6use std::time::Instant as StdInstant;
7
8pub use std::time::SystemTime;
10
11pub use chrono::Duration;
13
14#[derive(Debug, Clone, Copy)]
16pub struct Instant {
17 inner: StdInstant,
18}
19
20impl Instant {
21 pub fn duration_since(&self, earlier: &Instant) -> Duration {
23 let elapsed = self.inner.duration_since(earlier.inner);
24 Duration::from_std(elapsed).unwrap_or_else(|_| Duration::zero())
25 }
26}
27
28pub fn now() -> Instant {
30 Instant {
31 inner: StdInstant::now(),
32 }
33}
34
35pub fn timestamp() -> i64 {
37 Utc::now().timestamp()
38}
39
40pub fn now_millis() -> i64 {
42 Utc::now().timestamp_millis()
43}
44
45pub fn now_string() -> String {
47 Utc::now().to_rfc3339()
48}
49
50pub fn now_local() -> String {
52 Local::now().to_rfc3339()
53}
54
55pub fn parse(s: &str) -> Result<i64, String> {
57 s.parse::<DateTime<Utc>>()
58 .map(|dt| dt.timestamp())
59 .map_err(|e| e.to_string())
60}
61
62pub fn parse_format(s: &str, fmt: &str) -> Result<i64, String> {
64 DateTime::parse_from_str(s, fmt)
65 .map(|dt| dt.timestamp())
66 .map_err(|e| e.to_string())
67}
68
69pub fn format(timestamp: i64, format: &str) -> String {
71 DateTime::from_timestamp(timestamp, 0)
72 .unwrap_or_else(Utc::now)
73 .format(format)
74 .to_string()
75}
76
77pub fn sleep(secs: u64) {
79 std::thread::sleep(std::time::Duration::from_secs(secs));
80}
81
82pub fn sleep_millis(millis: u64) {
84 std::thread::sleep(std::time::Duration::from_millis(millis));
85}
86
87pub fn add_seconds(timestamp: i64, seconds: i64) -> i64 {
89 DateTime::from_timestamp(timestamp, 0)
90 .and_then(|dt| dt.checked_add_signed(Duration::seconds(seconds)))
91 .map(|dt| dt.timestamp())
92 .unwrap_or(timestamp)
93}
94
95pub fn add_days(timestamp: i64, days: i64) -> i64 {
97 DateTime::from_timestamp(timestamp, 0)
98 .and_then(|dt| dt.checked_add_signed(Duration::days(days)))
99 .map(|dt| dt.timestamp())
100 .unwrap_or(timestamp)
101}
102
103pub fn duration_secs(start: i64, end: i64) -> i64 {
105 end - start
106}
107
108pub fn duration_millis(start: i64, end: i64) -> i64 {
110 (end - start) * 1000
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn test_now() {
119 let ts = timestamp();
120 assert!(ts > 1_600_000_000); }
122
123 #[test]
124 fn test_now_string() {
125 let s = now_string();
126 assert!(s.contains('T')); assert!(s.contains('Z') || s.contains('+'));
129 }
130
131 #[test]
132 fn test_parse() {
133 let result = parse("2024-01-01T00:00:00Z");
134 assert!(result.is_ok());
135 }
136
137 #[test]
138 fn test_add_seconds() {
139 let ts = 1_700_000_000i64;
140 let new_ts = add_seconds(ts, 3600);
141 assert_eq!(new_ts, ts + 3600);
142 }
143
144 #[test]
145 fn test_add_days() {
146 let ts = 1_700_000_000i64;
147 let new_ts = add_days(ts, 1);
148 assert_eq!(new_ts, ts + 86400);
149 }
150}