|
1 | 1 | use anyhow::Result; |
| 2 | +use chrono::{DateTime, Utc}; |
2 | 3 | use clap::Parser; |
3 | 4 | use eframe::egui; |
4 | 5 | use eframe::wgpu::{self, util::DeviceExt}; |
@@ -136,36 +137,9 @@ fn current_timestamp_us() -> i64 { |
136 | 137 | /// Format a user timestamp (microseconds since Unix epoch) as |
137 | 138 | /// `yyyy-mm-dd hh:mm:ss.ssss`. |
138 | 139 | fn format_timestamp_us(ts_us: i64) -> String { |
139 | | - // Convert to calendar components without chrono — pure arithmetic. |
140 | | - let secs = (ts_us / 1_000_000) as u64; |
141 | | - let sub_sec_us = (ts_us % 1_000_000) as u32; |
142 | | - |
143 | | - // Days / time-of-day decomposition |
144 | | - let days = (secs / 86400) as i64; |
145 | | - let day_secs = (secs % 86400) as u32; |
146 | | - let hour = day_secs / 3600; |
147 | | - let minute = (day_secs % 3600) / 60; |
148 | | - let second = day_secs % 60; |
149 | | - let frac = sub_sec_us / 100; // 4-digit tenths of microseconds → 0..9999 |
150 | | - |
151 | | - // Convert days since epoch to y/m/d (civil calendar, proleptic Gregorian). |
152 | | - // Algorithm from Howard Hinnant (http://howardhinnant.github.io/date_algorithms.html) |
153 | | - let z = days + 719468; |
154 | | - let era = (if z >= 0 { z } else { z - 146096 }) / 146097; |
155 | | - let doe = (z - era * 146097) as u32; // day of era [0, 146096] |
156 | | - let yoe = |
157 | | - (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // year of era [0, 399] |
158 | | - let y = yoe as i64 + era * 400; |
159 | | - let doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // day of year [0, 365] |
160 | | - let mp = (5 * doy + 2) / 153; // [0, 11] |
161 | | - let day = doy - (153 * mp + 2) / 5 + 1; // [1, 31] |
162 | | - let month = if mp < 10 { mp + 3 } else { mp - 9 }; // [1, 12] |
163 | | - let year = if month <= 2 { y + 1 } else { y }; |
164 | | - |
165 | | - format!( |
166 | | - "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:04}", |
167 | | - year, month, day, hour, minute, second, frac |
168 | | - ) |
| 140 | + DateTime::<Utc>::from_timestamp_micros(ts_us) |
| 141 | + .map(|dt| dt.format("%Y-%m-%d %H:%M:%S%.4f").to_string()) |
| 142 | + .unwrap_or_else(|| format!("<invalid timestamp {ts_us}>")) |
169 | 143 | } |
170 | 144 |
|
171 | 145 | fn simulcast_state_full_dims(state: &Arc<Mutex<SimulcastState>>) -> Option<(u32, u32)> { |
|
0 commit comments