MCPcopy Create free account
hub / github.com/ScriptedAlchemy/tracedecay / parse_rfc3339_timestamp

Function parse_rfc3339_timestamp

src/timeutil.rs:14–85  ·  view source on GitHub ↗

Zero-dependency civil-date / RFC3339 timestamp parsing shared by the accounting transcript parser and the MCP LCM session handlers. This is the stricter of the two parsers it consolidates: it requires an explicit timezone (`Z` or `±HH:MM`), validates calendar ranges (month/day/leap years) and rejects trailing garbage, while still supporting fractional seconds (which are truncated). Parses a timez

(value: &str)

Source from the content-addressed store, hash-verified

12/// Returns `None` for missing/invalid timezone suffixes, out-of-range
13/// calendar or clock fields, or timestamps before the epoch.
14pub fn parse_rfc3339_timestamp(value: &str) -> Option<i64> {
15 let bytes = value.as_bytes();
16 if bytes.len() < 20
17 || bytes.get(4) != Some(&b'-')
18 || bytes.get(7) != Some(&b'-')
19 || !matches!(bytes.get(10), Some(b'T' | b't' | b' '))
20 || bytes.get(13) != Some(&b':')
21 || bytes.get(16) != Some(&b':')
22 {
23 return None;
24 }
25
26 let year = parse_fixed_i32(value, 0, 4)?;
27 let month = parse_fixed_u32(value, 5, 7)?;
28 let day = parse_fixed_u32(value, 8, 10)?;
29 let hour = parse_fixed_u32(value, 11, 13)?;
30 let minute = parse_fixed_u32(value, 14, 16)?;
31 let second = parse_fixed_u32(value, 17, 19)?;
32 if !(1..=12).contains(&month)
33 || hour > 23
34 || minute > 59
35 || second > 59
36 || day == 0
37 || day > days_in_month(year, month)
38 {
39 return None;
40 }
41
42 let mut zone_pos = 19;
43 if bytes.get(zone_pos) == Some(&b'.') {
44 zone_pos += 1;
45 let fraction_start = zone_pos;
46 while matches!(bytes.get(zone_pos), Some(b'0'..=b'9')) {
47 zone_pos += 1;
48 }
49 if zone_pos == fraction_start {
50 return None;
51 }
52 }
53
54 let offset_seconds = match bytes.get(zone_pos)? {
55 b'Z' | b'z' => {
56 if zone_pos + 1 != bytes.len() {
57 return None;
58 }
59 0
60 }
61 b'+' | b'-' => {
62 if zone_pos + 6 != bytes.len() || bytes.get(zone_pos + 3) != Some(&b':') {
63 return None;
64 }
65 let offset_hours = parse_fixed_i32(value, zone_pos + 1, zone_pos + 3)?;
66 let offset_minutes = parse_fixed_i32(value, zone_pos + 4, zone_pos + 6)?;
67 if offset_hours > 23 || offset_minutes > 59 {
68 return None;
69 }
70 let offset = offset_hours * 3600 + offset_minutes * 60;
71 if bytes[zone_pos] == b'+' {

Callers 3

resolve_backfill_sinceFunction · 0.85
parse_timestampFunction · 0.85

Calls 5

parse_fixed_i32Function · 0.85
parse_fixed_u32Function · 0.85
days_in_monthFunction · 0.85
days_from_civilFunction · 0.85
containsMethod · 0.45

Tested by

no test coverage detected