{"record":{"id":"7047ea831e01f71c","repo":"nautechsystems/nautilus_trader","slug":"valid-utc-day-start","errorCode":null,"errorMessage":"valid UTC day start","messagePattern":"valid UTC day start","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/bar.rs","lineNumber":341,"sourceCode":"            \"Aggregation type {} not supported for time bars\",\n            spec.aggregation\n        ),\n    }\n}\n\n/// Finds the closest smaller time based on a daily time origin and period.\n///\n/// This function calculates the most recent time that is aligned with the given period\n/// and is less than or equal to the current time.\nfn find_closest_smaller_time(\n    now: Timestamp,\n    daily_time_origin: SignedDuration,\n    period: SignedDuration,\n) -> Timestamp {\n    // Floor to start of day\n    let day_start = Offset::UTC\n        .to_timestamp(Offset::UTC.to_datetime(now).date().at(0, 0, 0, 0))\n        .expect(\"valid UTC day start\");\n    let base_time = day_start + daily_time_origin;\n\n    let time_difference = base_time.duration_until(now);\n    let period_ns = period.as_nanos();\n    debug_assert_ne!(period_ns, 0, \"bar period must be non-zero\");\n\n    // Use div_euclid for floor division (rounds toward -inf, not zero)\n    // so negative deltas (now before origin) yield the previous period boundary\n    let num_periods = time_difference.as_nanos().div_euclid(period_ns);\n\n    base_time + SignedDuration::from_nanos_i128(num_periods * period_ns)\n}\n\nfn duration_days(days: i64) -> SignedDuration {\n    try_duration_days(days).unwrap_or_else(|e| panic!(\"{e}\"))\n}\n\nfn try_duration_days(days: i64) -> anyhow::Result<SignedDuration> {","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/bar.rs#L323-L359","documentation":"`find_closest_smaller_time` floors the current time `now` to the start of its UTC calendar day, then offsets by `daily_time_origin` to find the closest time-bar origin. The `.expect(\"valid UTC day start\")` panics if the timezone library cannot convert a midnight datetime to a `Timestamp`. This is an internal invariant: a UTC midnight date should always convert, so a panic here means a corrupt `now` timestamp or a library bug.","triggerScenarios":"Calling `get_time_bar_start` (directly or via time-bar aggregation) with a `now` timestamp outside the representable date range of the chrono/Offset conversion, or with a `Timestamp` value that produces an out-of-range date when floored to midnight.","commonSituations":"Loading or synthesizing bars with corrupt extreme nanosecond timestamps (e.g. 0 or u64::MAX) from a bad data file; feeding sentinel timestamps into time-based aggregation; upgrading nautilus versions where timestamp range checks changed.","solutions":["Verify the `now` Timestamp passed to get_time_bar_start is a real timestamp within a sane range (e.g. 1970-2100) before aggregation","Check the source of the timestamp for corruption (data files, fixtures, deserialization)","Clamp or sanitize out-of-range timestamps upstream of time-bar aggregation","If it reproduces with a valid timestamp, report as a bug to the nautilus_trader maintainers"],"exampleFix":"// before\nlet start = get_time_bar_start(ts_event, daily_time_origin, period);\n// after\nconst MIN_TS: u64 = 0;\nconst MAX_TS: u64 = 4_102_444_800_000_000_000; // ~2100-01-01 in ns\nassert!(ts_event.as_u64() > MIN_TS && ts_event.as_u64() < MAX_TS, \"timestamp out of range\");\nlet start = get_time_bar_start(ts_event, daily_time_origin, period);","handlingStrategy":"validation","validationCode":"def assert_valid_timestamp(ts_ns: int) -> int:\n    if not (0 < ts_ns < 4_102_444_800_000_000_000):  # ~2100-01-01 ns\n        raise ValueError(f\"timestamp {ts_ns} outside sane range\")\n    return ts_ns","typeGuard":"def is_valid_unix_nanos(ts_ns: int) -> bool:\n    return isinstance(ts_ns, int) and 0 < ts_ns < 4_102_444_800_000_000_000","tryCatchPattern":null,"preventionTips":["Sanitize timestamps loaded from external data before aggregation","Never feed sentinel/placeholder timestamps into time-bar logic","Range-check timestamps at ingestion boundaries"],"tags":["rust","panic","timestamp","bar-aggregation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}