You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Define time zone conversion for values whose zone cannot be represented #1220
time with time zone keeps returning an aware time with a fixed offset.
Add the dependency floor tzdata>=2024.2 (IANA 2024b).
All of these ship in 4.2.0. This issue's own PR adds the DataError cases to the shared converter and the tzdata floor, and closes this issue. #1217 adds the column name to the error and unwraps the OperationalError of PandasCursor whole reads; #1219 makes the PandasCursor checks vectorized.
Named zones come only from SQL expressions. An Iceberg timestamp(6) with time zone column stores the instant and reads back as ... UTC, whatever zone was inserted. Hive tables have no time zone type. The session time zone is UTC. A named zone appears in a result only when the query produces one, for example with at_timezone(), AT TIME ZONE, with_timezone(), or from_unixtime(x, zone).
The DST fall-back hour is written ambiguously.2020-11-01 05:30 UTC and 06:30 UTC both print as 2020-11-01 01:30:00 America/New_York. The same holds for Europe/London and Australia/Lord_Howe (30-minute DST). Athena parses that text, as a literal or through with_timezone(), as the earlier instant, which is Python's fold=0.
Athena never writes a nonexistent local time. It formats from the instant. A literal in the DST gap is rejected with INVALID_LITERAL, and with_timezone() shifts it forward. A nonexistent time can appear only when Athena's and Python's time zone rules differ.
Athena's time zone database is older than tzdata 2025a. It rejects America/Coyhaique (2025b) and uses the earlier Paraguay rules. For 549 zone keys × 10 instants from 1600 to 9999, the instant Python computes from Athena's text differed from to_unixtime() in 11 cases:
America/Asuncion from 2026: 1 hour, with macOS's 2026c database.
Africa/Casablanca and Africa/El_Aaiun from 2038: 1 hour.
Asia/Manila in 1600: 8 seconds.
The text carries no offset, so these differences cannot be detected.
Unknown zone names. Every zone key in Trino's zone index except America/Coyhaique, which Athena rejects, is in tzdata 2024b. Python reports a zone name as unknown only when its time zone database is older than Athena's. zoneinfo searches the system TZPATH before the tzdata package.
time with time zone always carries an offset (03:04:05.123-04:00). TIME '... America/New_York' is rejected, and a cast from a named-zone timestamp yields an offset. Offsets range from -14:00 to +14:00, in minutes.
Zone keys are written as given.US/Eastern stays US/Eastern, UTC+3 becomes +03:00, Etc/GMT+3 becomes -03:00, and Z becomes UTC.
pandas 3.0.6. An object column with one zone infers datetime64[us, <zone>], and one with two zones stays object. tz_localize(ambiguous="raise", nonexistent="raise") detects both cases without converting row by row.
Decision
Case
Fetch methods and PandasCursor
Offset
Exact: a fixed-offset timezone
Zone name known to Python, including UTC
ZoneInfo
Zone name unknown to Python's time zone database, including an environment without time zone data
DataError naming the column and the zone, suggesting an update of tzdata
Ambiguous local time (DST fall-back)
DataError naming the column, suggesting AT TIME ZONE 'UTC' or to_unixtime()
Nonexistent local time (DST gap)
DataError naming the column
Rules that differ between Athena and Python
Not detectable. The value is converted by Python's rules, and the limitation is documented with the same SQL workaround.
No option returns fold=0 for ambiguous values. Named zones come only from the user's SQL, and converting there gives the exact instant. fold=0 would return the wrong instant for half of the values in that hour.
Arrow and Polars keep these columns as text, so these cases apply only where values are converted: fetch methods and PandasCursor.
Add the dependency floor tzdata>=2024.2 (IANA 2024b) so that every zone name Athena accepts today is known. The floor does not make the rules match.
All of these ship in 4.2.0. Implementation: DataError cases in the shared converter and the tzdata floor in this issue's PR; the column name in the error in #1217; PandasCursor UTC normalization with vectorized ambiguity checks in #1219; documentation of the limitation and the SQL workaround in #1221.
Activity
laughingman7743 commentedon Oct 16, 2026
Measurements (live Athena engine v3, 2026-10-17)
Named zones come only from SQL expressions. An Iceberg
timestamp(6) with time zonecolumn stores the instant and reads back as... UTC, whatever zone was inserted. Hive tables have no time zone type. The session time zone isUTC. A named zone appears in a result only when the query produces one, for example withat_timezone(),AT TIME ZONE,with_timezone(), orfrom_unixtime(x, zone).The DST fall-back hour is written ambiguously.
2020-11-01 05:30 UTCand06:30 UTCboth print as2020-11-01 01:30:00 America/New_York. The same holds forEurope/LondonandAustralia/Lord_Howe(30-minute DST). Athena parses that text, as a literal or throughwith_timezone(), as the earlier instant, which is Python'sfold=0.Athena never writes a nonexistent local time. It formats from the instant. A literal in the DST gap is rejected with
INVALID_LITERAL, andwith_timezone()shifts it forward. A nonexistent time can appear only when Athena's and Python's time zone rules differ.Athena's time zone database is older than tzdata 2025a. It rejects
America/Coyhaique(2025b) and uses the earlier Paraguay rules. For 549 zone keys × 10 instants from 1600 to 9999, the instant Python computes from Athena's text differed fromto_unixtime()in 11 cases:America/Asuncionfrom 2026: 1 hour, with macOS's 2026c database.Africa/CasablancaandAfrica/El_Aaiunfrom 2038: 1 hour.Asia/Manilain 1600: 8 seconds.The text carries no offset, so these differences cannot be detected.
Unknown zone names. Every zone key in Trino's zone index except
America/Coyhaique, which Athena rejects, is in tzdata 2024b. Python reports a zone name as unknown only when its time zone database is older than Athena's.zoneinfosearches the systemTZPATHbefore thetzdatapackage.time with time zonealways carries an offset (03:04:05.123-04:00).TIME '... America/New_York'is rejected, and a cast from a named-zone timestamp yields an offset. Offsets range from-14:00to+14:00, in minutes.Zone keys are written as given.
US/EasternstaysUS/Eastern,UTC+3becomes+03:00,Etc/GMT+3becomes-03:00, andZbecomesUTC.pandas 3.0.6. An object column with one zone infers
datetime64[us, <zone>], and one with two zones staysobject.tz_localize(ambiguous="raise", nonexistent="raise")detects both cases without converting row by row.Decision
timezoneUTCZoneInfoDataErrornaming the column and the zone, suggesting an update oftzdataDataErrornaming the column, suggestingAT TIME ZONE 'UTC'orto_unixtime()DataErrornaming the columndatetime64[us, UTC], as in #1212time with time zonetimewith a fixed-offsettimezonefold=0for ambiguous values. Named zones come only from the user's SQL, and converting there gives the exact instant.fold=0would return the wrong instant for half of the values in that hour.tzdata>=2024.2(IANA 2024b) so that every zone name Athena accepts today is known. The floor does not make the rules match.All of these ship in 4.2.0. Implementation:
DataErrorcases in the shared converter and thetzdatafloor in this issue's PR; the column name in the error in #1217; PandasCursor UTC normalization with vectorized ambiguity checks in #1219; documentation of the limitation and the SQL workaround in #1221.Cover the time zone cases decided in #1220
Cover the time zone cases decided in #1220
Follow the time zone errors of #1220 and simulate an older tzdata