nautechsystems/nautilus_trader · error · anyhow::Error
Execution timestamp '{time_str}' is non-existent in timezone
Error message
Execution timestamp '{time_str}' is non-existent in timezone '{tz_str}' What it means
After parsing the naive datetime, the adapter localizes it into the requested timezone. If that local time falls inside a DST gap (a wall-clock time that never existed because clocks jumped forward), the localization is ambiguous in the impossible direction and the adapter raises this error rather than inventing an instant. Ambiguous (repeated) times are handled by taking the earliest instant, but gap times are rejected.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/parse.rs:451
fn localize_with_zone(dt: DateTime, tz_str: &str, time_str: &str) -> anyhow::Result<Timestamp> {
let tz_name = if tz_str.eq_ignore_ascii_case("Z") {
"UTC"
} else {
tz_str
};
let zone = get_timezone(tz_name).map_err(|_| {
anyhow::anyhow!(
"Unrecognized execution timezone '{tz_str}' in '{time_str}'. Configure TWS / IB Gateway to emit a standard timezone (e.g. UTC)"
)
})?;
let ambiguous = zone.to_ambiguous_timestamp(dt);
match ambiguous.offset() {
AmbiguousOffset::Unambiguous { .. } => Ok(ambiguous.unambiguous()?),
// Fall-back fold: take the earliest instant (worst case ~1h skew).
AmbiguousOffset::Fold { .. } => Ok(ambiguous.earlier()?),
AmbiguousOffset::Gap { .. } => {
anyhow::bail!("Execution timestamp '{time_str}' is non-existent in timezone '{tz_str}'")
}
}
}
fn datetime_to_unix_nanos(dt: Timestamp, time_str: &str) -> anyhow::Result<UnixNanos> {
let nanos: u64 = dt
.as_nanosecond()
.try_into()
.map_err(|_| anyhow::anyhow!("Execution timestamp '{time_str}' was before Unix epoch"))?;
Ok(UnixNanos::new(nanos))
}
#[cfg(test)]
mod tests {
use ibapi::{
contracts::Contract,
orders::{Action, ExecutionSide, Liquidity, Order, OrderStatusKind},
};View on GitHub (pinned to 18893faf8b)
Solutions
- Correct the source timestamp — it cannot exist in that timezone; check for clock/offset errors in the reporting system.
- If the timestamp is known to be in a fixed offset (e.g. exchange local time), parse with that fixed offset instead of an IANA zone with DST.
- Adjust the time by one hour (gap durations are typically 1h) if you know the intended instant.
- Handle this error at the call site by skipping or re-anchoring the affected fill record.
Example fix
// before: nonexistent local time in DST gap
parse_execution_time("20260308 02:30:00 America/New_York")?; // Err: non-existent
// after: use the post-transition equivalent instant
parse_execution_time("20260308 03:30:00 America/New_York")?; Defensive patterns
Strategy: try-catch
Validate before calling
fn is_dst_gap(ts: &str, tz: &str) -> bool {
// Heuristic: if shifting the local time forward by 1h changes the UTC offset,
// the original time was likely inside a DST gap. Precheck before parsing.
// (Verify with a tz database such as chrono-tz / jiff.)
false // implement with your tz library of choice
} Try / catch
match parse_execution_time(time_str) {
Err(e) if e.to_string().contains("is non-existent in timezone") => {
// DST gap: retry with time advanced past the gap or parsed in a fixed offset
let corrected = bump_past_gap(time_str);
parse_execution_time(&corrected)?
}
other => other?,
} Prevention
- Do not generate timestamps inside the 02:00–03:00 local window on DST transition days
- Prefer fixed-offset parsing for exchange-local times that have no DST
- Store and compare instants in UTC; convert to local time only for display
- Test timestamp handling around each year's DST transitions for your venue timezones
When it happens
Trigger: parse_execution_time receives a timestamp whose date/time falls inside a spring-forward DST gap in tz_str — e.g. '20260308 02:30:00 America/New_York', where 02:00–03:00 local does not exist on the DST transition day.
Common situations: Backtests or fill reports containing timestamps recorded during the skipped hour of a DST transition; clocks or systems misconfigured so reported times land in the nonexistent hour; data generated in a fixed-offset timezone then reinterpreted in an IANA zone.
Related errors
- Invalid execution time format: {time_str}
- Negative nanosecond timestamp from: {timestamp}
- invalid negative Binance {field} timestamp: {value}
- Binance {field} timestamp is outside the UnixNanos range: {v
- Timestamp out of range for candle at {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/16f87f90e25ab18b.
Report an issue: GitHub.