Description
Tracker::first_seen_days() in src/core/tracking.rs always returns 0 because the timestamp parsing format doesn't match the storage format.
Root Cause
Timestamps are stored via Utc::now().to_rfc3339() (line 423), producing strings like:
2026-06-28T12:00:00.123456+00:00
But first_seen_days() (line 1108) tries to parse with:
NaiveDateTime::parse_from_str(&ts, "%Y-%m-%dT%H:%M:%S")
This fails because:
- Fractional seconds (
.123456) aren't in the format string
- Timezone offset (
+00:00) isn't in the format string
NaiveDateTime::parse_from_str requires the entire input to match
The second fallback format (%Y-%m-%d %H:%M:%S) also fails (wrong separator).
Both parse attempts fail, triggering unwrap_or_else(|_| chrono::Utc::now()) — so first is always "now", and (now - now).num_days() is always 0.
Comparison
Line 951 in the same file correctly parses timestamps:
DateTime::parse_from_rfc3339(&row.get::<_, String>(0)?)
.map(|dt| dt.with_timezone(&Utc))
Impact
- Telemetry reports installation age as 0 days regardless of actual usage history
- Any feature relying on
first_seen_days() gets incorrect data
Fix
Use DateTime::parse_from_rfc3339() as the primary parser, keeping the existing NaiveDateTime formats as fallbacks for databases created by older RTK versions.
Description
Tracker::first_seen_days()insrc/core/tracking.rsalways returns 0 because the timestamp parsing format doesn't match the storage format.Root Cause
Timestamps are stored via
Utc::now().to_rfc3339()(line 423), producing strings like:But
first_seen_days()(line 1108) tries to parse with:This fails because:
.123456) aren't in the format string+00:00) isn't in the format stringNaiveDateTime::parse_from_strrequires the entire input to matchThe second fallback format (
%Y-%m-%d %H:%M:%S) also fails (wrong separator).Both parse attempts fail, triggering
unwrap_or_else(|_| chrono::Utc::now())— sofirstis always "now", and(now - now).num_days()is always 0.Comparison
Line 951 in the same file correctly parses timestamps:
Impact
first_seen_days()gets incorrect dataFix
Use
DateTime::parse_from_rfc3339()as the primary parser, keeping the existingNaiveDateTimeformats as fallbacks for databases created by older RTK versions.