sage_runtime/stdlib/
time.rs1use chrono::{DateTime, TimeZone, Utc};
4use std::time::{SystemTime, UNIX_EPOCH};
5
6#[must_use]
8pub fn now_ms() -> i64 {
9 SystemTime::now()
10 .duration_since(UNIX_EPOCH)
11 .expect("time went backwards")
12 .as_millis() as i64
13}
14
15#[must_use]
17pub fn now_s() -> i64 {
18 SystemTime::now()
19 .duration_since(UNIX_EPOCH)
20 .expect("time went backwards")
21 .as_secs() as i64
22}
23
24#[must_use]
36pub fn format_timestamp(timestamp_ms: i64, format: &str) -> String {
37 let secs = timestamp_ms / 1000;
38 let nanos = ((timestamp_ms % 1000) * 1_000_000) as u32;
39 let dt: DateTime<Utc> = Utc.timestamp_opt(secs, nanos).unwrap();
40 dt.format(format).to_string()
41}
42
43pub fn parse_timestamp(s: &str, format: &str) -> Result<i64, String> {
47 let dt = DateTime::parse_from_str(s, format)
48 .or_else(|_| {
49 chrono::NaiveDateTime::parse_from_str(s, format).map(|d| d.and_utc().fixed_offset())
51 })
52 .map_err(|e| {
53 format!(
54 "failed to parse timestamp '{}' with format '{}': {}",
55 s, format, e
56 )
57 })?;
58 Ok(dt.timestamp_millis())
59}
60
61pub const MS_PER_SECOND: i64 = 1000;
63pub const MS_PER_MINUTE: i64 = 60_000;
64pub const MS_PER_HOUR: i64 = 3_600_000;
65pub const MS_PER_DAY: i64 = 86_400_000;
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_now_ms() {
73 let ms1 = now_ms();
74 let ms2 = now_ms();
76 assert!(ms2 >= ms1);
77 }
78
79 #[test]
80 fn test_now_s() {
81 let s = now_s();
82 assert!(s > 1_700_000_000); }
85
86 #[test]
87 fn test_format_timestamp() {
88 let ts = 1705315800000_i64;
90 assert_eq!(format_timestamp(ts, "%Y-%m-%d"), "2024-01-15");
91 assert_eq!(format_timestamp(ts, "%H:%M:%S"), "10:50:00");
92 }
93
94 #[test]
95 fn test_parse_timestamp() {
96 let result = parse_timestamp("2024-01-15 10:50:00 +0000", "%Y-%m-%d %H:%M:%S %z");
98 assert!(result.is_ok());
99 assert_eq!(result.unwrap(), 1705315800000);
100 }
101
102 #[test]
103 fn test_constants() {
104 assert_eq!(MS_PER_SECOND, 1000);
105 assert_eq!(MS_PER_MINUTE, 60 * 1000);
106 assert_eq!(MS_PER_HOUR, 60 * 60 * 1000);
107 assert_eq!(MS_PER_DAY, 24 * 60 * 60 * 1000);
108 }
109}