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

  1. Correct the source timestamp — it cannot exist in that timezone; check for clock/offset errors in the reporting system.
  2. 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.
  3. Adjust the time by one hour (gap durations are typically 1h) if you know the intended instant.
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/16f87f90e25ab18b. Report an issue: GitHub.