{"record":{"id":"ca5553d8cb753647","repo":"clockworklabs/SpacetimeDB","slug":"systemtime-predates-the-unix-epoch","errorCode":null,"errorMessage":"SystemTime predates the Unix epoch","messagePattern":"SystemTime predates the Unix epoch","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/sats/src/timestamp.rs","lineNumber":110,"sourceCode":"            Ok(positive) => SystemTime::UNIX_EPOCH\n                .checked_add(positive)\n                .expect(\"Timestamp with i64 microseconds since Unix epoch overflows SystemTime\"),\n            Err(negative) => SystemTime::UNIX_EPOCH\n                .checked_sub(negative)\n                .expect(\"Timestamp with i64 microseconds before Unix epoch overflows SystemTime\"),\n        }\n    }\n\n    /// Convert a [`SystemTime`] into a [`Timestamp`] which refers to approximately the same point in time.\n    ///\n    /// This conversion may panic if `system_time` is out of bounds for [`Duration`].\n    /// [`SystemTime`]'s range is larger than [`Timestamp`] on both Unix and Windows targets,\n    /// so times in the far past or far future may panic.\n    /// [`Timestamp`]'s range is approximately 292 years before and after the Unix epoch.\n    pub fn from_system_time(system_time: SystemTime) -> Self {\n        let duration = system_time\n            .duration_since(SystemTime::UNIX_EPOCH)\n            .expect(\"SystemTime predates the Unix epoch\");\n        Self::from_duration_since_unix_epoch(duration)\n    }\n\n    /// Returns the [`Duration`] delta between `self` and `earlier`, if `earlier` predates `self`.\n    ///\n    /// Returns `None` if `earlier` is strictly greater than `self`,\n    /// or if the difference between `earlier` and `self` overflows an `i64`.\n    pub fn duration_since(self, earlier: Timestamp) -> Option<Duration> {\n        self.time_duration_since(earlier)?.to_duration().ok()\n    }\n\n    /// Returns the [`TimeDuration`] delta between `self` and `earlier`.\n    ///\n    /// The result may be negative if `earlier` is actually later than `self`.\n    ///\n    /// Returns `None` if the subtraction overflows or underflows `i64` microseconds.\n    pub fn time_duration_since(self, earlier: Timestamp) -> Option<TimeDuration> {\n        let delta = self","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/sats/src/timestamp.rs#L92-L128","documentation":"`Timestamp::from_system_time` calls `system_time.duration_since(SystemTime::UNIX_EPOCH).expect(\"SystemTime predates the Unix epoch\")`, so converting any SystemTime earlier than 1970-01-01 panics — even though Timestamp itself can represent pre-epoch times via signed micros. The trigger is a clock reading before 1970 or code that computes UNIX_EPOCH minus a duration.","triggerScenarios":"Passing `SystemTime::UNIX_EPOCH - Duration::from_secs(...)` (e.g. tests simulating past dates), or a machine clock erroneously set pre-1970 (dead RTC battery, unsynced VM), into from_system_time.","commonSituations":"Unit tests of date logic that subtract from the epoch; VMs or embedded boards with dead/unsynchronized RTCs; accidental negative durations in time math.","solutions":["Handle pre-epoch times explicitly: match on duration_since's Err and build `Timestamp::from_micros_since_unix_epoch(-micros)` instead of converting via from_system_time.","Fix the host clock (NTP/systemd-timesyncd) if it genuinely reads before 1970.","Avoid computing UNIX_EPOCH - dur and feeding the result to from_system_time."],"exampleFix":"// before: panics because the value predates the epoch\nlet ts = Timestamp::from_system_time(SystemTime::UNIX_EPOCH - Duration::from_secs(60));\n\n// after: construct pre-epoch values from signed micros\nlet ts = match SystemTime::UNIX_EPOCH.checked_sub(Duration::from_secs(60)) {\n    Some(t) if t >= SystemTime::UNIX_EPOCH => Timestamp::from_system_time(t),\n    _ => Timestamp::from_micros_since_unix_epoch(-60_000_000),\n};","handlingStrategy":"validation","validationCode":"if system_time >= SystemTime::UNIX_EPOCH {\n    let ts = Timestamp::from_system_time(system_time);\n} else {\n    // build from signed micros: Timestamp::from_micros_since_unix_epoch(-micros)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match on duration_since's Result instead of expecting Ok.","Keep host clocks NTP-synced, especially VMs and boards with RTC batteries.","In tests, construct pre-epoch values from signed micros rather than subtracting from UNIX_EPOCH."],"tags":["rust","timestamp","unix-epoch","clock","spacetimedb-sats"],"backgroundTag":"systemtime-before-epoch","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}