pola-rs/polars · error

activate 'timezones' feature

Error message

activate 'timezones' feature

What it means

While initializing the CSV serializer for Datetime columns, polars formats a sample timestamp to fail fast on bad format strings. Localizing that sample to a time zone requires chrono-tz, which is only present with the timezones cargo feature; without it, the cfg(not(feature = "timezones")) arm panics as soon as a tz-aware Datetime column is written, even if the format string is fine.

Source

Thrown at crates/polars-io/src/csv/write/write_impl/serializer.rs:817

        )?,
        #[cfg(feature = "dtype-datetime")]
        DataType::Datetime(time_unit, _) => {
            let format = chrono::format::StrftimeItems::new(_datetime_format)
                .parse()
                .map_err(|_| {
                    polars_err!(
                        ComputeError: "cannot format {} with format '{_datetime_format}'",
                        if _time_zone.is_some() { "DateTime" } else { "NaiveDateTime" },
                    )
                })?;
            use std::fmt::Write;
            let sample_datetime = match _time_zone {
                #[cfg(feature = "timezones")]
                Some(time_zone) => time_zone
                    .from_utc_datetime(&chrono::NaiveDateTime::MAX)
                    .format_with_items(format.iter()),
                #[cfg(not(feature = "timezones"))]
                Some(_) => panic!("activate 'timezones' feature"),
                None => chrono::NaiveDateTime::MAX.format_with_items(format.iter()),
            };
            // Fail fast for invalid format. This return error faster to the user, and allows us to not return
            // `Result` from `serialize()`.
            write!(IgnoreFmt, "{sample_datetime}").map_err(|_| {
                polars_err!(
                    ComputeError: "cannot format {} with format '{_datetime_format}'",
                    if _time_zone.is_some() { "DateTime" } else { "NaiveDateTime" },
                )
            })?;

            let array = array.as_any().downcast_ref().unwrap();

            macro_rules! time_unit_serializer {
                ($convert:ident) => {
                    match _time_zone {
                        #[cfg(feature = "timezones")]
                        Some(time_zone) => {

View on GitHub (pinned to 9b5d73fd00)

Solutions

  1. Enable the timezones feature on your polars dependency (features = ["timezones"])
  2. Or strip the zone before writing: df.with_column(col("ts").dt().replace_time_zone(None))
  3. Or write Parquet/NDJSON instead - they do not go through this strftime path

Example fix

// before (panics in a build without the `timezones` feature)
let bytes = df.clone().write_csv()?;

// after (choose one)
// 1) Cargo.toml: polars = { version = "...", features = ["timezones"] }
// 2) drop the tz first:
let df = df.with_column(col("ts").dt().replace_time_zone(None).alias("ts"))?;
let bytes = df.write_csv()?;
Defensive patterns

Strategy: fallback

Validate before calling

fn has_tz_aware_datetime(df: &DataFrame) -> bool {
    df.schema().iter_values().any(|dt| matches!(dt, DataType::Datetime(_, Some(_))))
}
// if true and your build lacks the `timezones` feature, strip zones before writing:
// df.apply("ts", |s| s.datetime().map(|ca| ca.replace_time_zone(None).into_series()))?;

Try / catch

catch_unwind(AssertUnwindSafe(|| df.write_csv(...))) only converts the panic to an error message; prefer the schema pre-check + replace_time_zone(None) fallback so the write never enters the failing branch.

Prevention

When it happens

Trigger: df.write_csv() (or CsvWriter) over a DataFrame containing DataType::Datetime(_, Some(tz)) - with or without a custom date_format - in a build where the timezones feature is off.

Common situations: Reading tz-aware parquet/IPC and dumping to CSV in a trimmed Rust build; code that worked in python-polars (features always on) failing after a port; feature drift after a dependency upgrade.

Related errors


AI-assisted analysis of pola-rs/polars@9b5d73fd00 (2026-08-19). Data as JSON: /api/errors/6e7ac40bde47ec01. Report an issue: GitHub.