MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / parse_utc_timestamp

Function parse_utc_timestamp

nodedb/src/storage/snapshot_restore.rs:101–153  ·  view source on GitHub ↗

Parse a UTC timestamp from various input formats. Supports: - Unix epoch microseconds: `"1710509400000000"` - Unix epoch seconds: `"1710509400"` - ISO 8601: `"2024-03-15T14:30:00Z"` (basic parsing, no full chrono dependency)

(input: &str)

Source from the content-addressed store, hash-verified

99/// - Unix epoch seconds: `"1710509400"`
100/// - ISO 8601: `"2024-03-15T14:30:00Z"` (basic parsing, no full chrono dependency)
101pub fn parse_utc_timestamp(input: &str) -> crate::Result<u64> {
102 let trimmed = input.trim();
103
104 // Try parsing as integer (epoch micros or seconds).
105 if let Ok(n) = trimmed.parse::<u64>() {
106 // Heuristic: values > 1e15 are microseconds, otherwise seconds.
107 if n > 1_000_000_000_000_000 {
108 return Ok(n); // Already microseconds.
109 }
110 return Ok(n * 1_000_000); // Convert seconds to microseconds.
111 }
112
113 // Try ISO 8601 basic parsing: "YYYY-MM-DDTHH:MM:SSZ"
114 // This is a simplified parser — production should use chrono or time crate.
115 if trimmed.len() >= 19 && trimmed.contains('T') {
116 let date_part = &trimmed[..10]; // "YYYY-MM-DD"
117 let time_part = &trimmed[11..19]; // "HH:MM:SS"
118
119 let parts: Vec<u64> = date_part
120 .split('-')
121 .chain(time_part.split(':'))
122 .filter_map(|s| s.parse().ok())
123 .collect();
124
125 if parts.len() == 6 {
126 let (year, month, day, hour, min, sec) =
127 (parts[0], parts[1], parts[2], parts[3], parts[4], parts[5]);
128
129 // Days from Unix epoch to the given date.
130 // Leap year: divisible by 4, except centuries unless divisible by 400.
131 let leap_days = |y: u64| -> u64 {
132 if y == 0 {
133 return 0;
134 }
135 let y = y - 1; // count leap years before this year
136 y / 4 - y / 100 + y / 400 - (1969 / 4 - 1969 / 100 + 1969 / 400)
137 };
138 let is_leap =
139 |y: u64| y.is_multiple_of(4) && (!y.is_multiple_of(100) || y.is_multiple_of(400));
140 let leap_adj = if is_leap(year) && month > 2 { 1 } else { 0 };
141 let days_since_epoch =
142 (year - 1970) * 365 + leap_days(year) + month_to_days(month) + leap_adj + day - 1;
143 let epoch_secs = days_since_epoch * 86400 + hour * 3600 + min * 60 + sec;
144 return Ok(epoch_secs * 1_000_000);
145 }
146 }
147
148 Err(crate::Error::BadRequest {
149 detail: format!(
150 "cannot parse UTC timestamp: '{trimmed}'. Expected epoch micros, epoch seconds, or ISO 8601"
151 ),
152 })
153}
154
155/// Approximate days from Jan 1 to the start of the given month (non-leap year).
156fn month_to_days(month: u64) -> u64 {

Callers 1

resolve_pitr_utcMethod · 0.85

Calls 6

month_to_daysFunction · 0.85
collectMethod · 0.80
lenMethod · 0.45
containsMethod · 0.45
okMethod · 0.45
parseMethod · 0.45

Tested by

no test coverage detected