{"record":{"id":"d365abc60d79f338","repo":"nautechsystems/nautilus_trader","slug":"invalid-date","errorCode":null,"errorMessage":"Invalid date","messagePattern":"Invalid date","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/datetime.rs","lineNumber":497,"sourceCode":"    );\n    out.push('Z');\n    out\n}\n\n/// Floor the given UNIX nanoseconds to the nearest microsecond.\n#[must_use]\npub const fn floor_to_nearest_microsecond(unix_nanos: u64) -> u64 {\n    (unix_nanos / NANOSECONDS_IN_MICROSECOND) * NANOSECONDS_IN_MICROSECOND\n}\n\n/// Calculates the last weekday (Mon-Fri) from the given `year`, `month`, and `day`.\n///\n/// # Errors\n///\n/// Returns an error if the date is invalid.\npub fn last_weekday_nanos(year: i32, month: u32, day: u32) -> anyhow::Result<UnixNanos> {\n    let date = Date::new(\n        i16::try_from(year).map_err(|_| anyhow::anyhow!(\"Invalid date\"))?,\n        i8::try_from(month).map_err(|_| anyhow::anyhow!(\"Invalid date\"))?,\n        i8::try_from(day).map_err(|_| anyhow::anyhow!(\"Invalid date\"))?,\n    )\n    .map_err(|_| anyhow::anyhow!(\"Invalid date\"))?;\n    let current_weekday = date.weekday().to_monday_one_offset();\n\n    // Calculate the offset in days for closest weekday (Mon-Fri)\n    let offset = match current_weekday {\n        1..=5 => 0, // Monday to Friday, no adjustment needed\n        6 => 1,     // Saturday, adjust to previous Friday\n        _ => 2,     // Sunday, adjust to previous Friday\n    };\n    // Calculate last closest weekday\n    let last_closest = date.checked_sub(Span::new().days(offset))?;\n\n    // Convert to UNIX nanoseconds\n    let unix_timestamp_ns = last_closest\n        .at(0, 0, 0, 0)","sourceCodeStart":479,"sourceCodeEnd":515,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/datetime.rs#L479-L515","documentation":"In last_weekday_nanos the i32 year cannot be converted to the i16 range Date::new requires, so the try_from fails and the function reports a generic \"Invalid date\". The library throws it because the year is outside the representable date range (roughly -32768..32767) and a real calendar date cannot be constructed. The message is intentionally generic; check which parameter is out of range.","triggerScenarios":"Calling last_weekday_nanos(year, month, day) with a year that does not fit in i16, e.g. year <= -32769 or year >= 32768, such as year=99999 from a bad config or 0/uninitialized value.","commonSituations":"Uninitialized/default (0 is fine, but sentinel values like i32::MAX are not); reading a year column from CSV parsed as i32 with junk; computing expiry years with an off-by-thousands arithmetic bug.","solutions":["Clamp or validate the year to the i16-representable calendar range before calling (practically 1..=9999).","Verify the source of the year value; fix upstream arithmetic or parsing that produced an out-of-range year.","Catch the error and surface the original year/month/day for diagnostics, since the message does not include them."],"exampleFix":"// before\nlet ns = last_weekday_nanos(expiry_year, month, day)?; // expiry_year = 120000\n// after\nassert!((1..=9999).contains(&expiry_year));\nlet ns = last_weekday_nanos(expiry_year, month, day)?;","handlingStrategy":"validation","validationCode":"// Rust: check year range before calling\nfn valid_year(y: i32) -> bool { (1..=9999).contains(&y) }","typeGuard":null,"tryCatchPattern":"let ns = last_weekday_nanos(year, month, day)\n    .map_err(|e| e.context(format!(\"last_weekday for y={year} m={month} d={day}\")))?;","preventionTips":["Validate year/month/day triples at config-load time, not at use time.","Guard against sentinel values like i32::MAX leaking into date fields."],"tags":["datetime","range-check","rust"],"backgroundTag":"value-out-of-range","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"}