Tested fix · Updated
Canada's November 1 time change in MongoDB, Elasticsearch, OpenSearch, Trino and DuckDB: checks and tested fixes
On 1 November 2026 Alberta, the Northwest Territories and Manitoba stop falling back, and British Columbia stops on the same day. From 02:00 local time that morning, software with the old time-zone rules puts Vancouver, Calgary, Edmonton, Inuvik and Winnipeg one hour behind. Morocco changed on 20 September, so old rules are already wrong there. Our runtimes guide covers Java, Go, PHP, Kubernetes CronJobs and MySQL.
These five data platforms each keep their own copy of the time-zone rules and ignore the operating system's copy. Updating the operating system doesn't fix them. These releases still carry old rules:
- MongoDB 9.0, 8.0 and 7.0: wrong now for Morocco, and from 1 November for British Columbia, Alberta, Inuvik and Manitoba.
- Elasticsearch up to 9.5.5, 9.4.8 and 8.19.23, and OpenSearch 3.9 and 2.19: wrong now for Morocco, and from 1 November for Alberta, Inuvik and Manitoba. Elasticsearch 9.5.6, 9.4.9 and 8.19.24, released on 2 November, carry the new rules.
- Trino 484, released on 15 October, updated only one of its two copies of the rules. It is wrong now for Morocco, and from 1 November it prints times in Edmonton, Inuvik and Winnipeg with the old offset, so a day start from
date_truncshows as 23:00 the evening before. 483 is wrong now for Morocco, and from 1 November for Vancouver, Edmonton, Inuvik and Winnipeg. - DuckDB 1.5.6 is wrong for Manitoba. 1.4.5 is wrong for all four, and for Morocco now.
What breaks is anything grouped by local day or hour: daily rollups, date_histogram buckets, $dateToString, date_trunc. In Winnipeg, an event between midnight and 01:00 lands on the previous day.
Each platform has a check below and a fix we tested on its current releases. None needs a vendor update. We ran every check and fix on 14 October 2026, and Trino 484, MongoDB 9.0.4 and OpenSearch 2.19.7 on 28 October, and the checks on Elasticsearch 9.5.6 and 8.19.24 on 3 November, on Linux x86-64, using the official container images. ClickHouse's newest supported releases already carry the new rules (see the table).
To check a whole image, including copies inside plugin jars such as Trino's Joda-Time, tzscan lists the copies of the time-zone data it recognises, without running the image.
Want us to check your image? Send us the name and tag or digest of a public Linux x86-64 container image, or the base image and runtime versions you use. Our AI agents run the applicable checks from our Canada guides and scan for the separate copies of the time-zone rules that our scanner recognizes. For a described stack, we first agree a test image and its limits with you; it is a reconstruction, not your deployed image.
Within 24 hours of your email, we send the result or tell you we cannot complete the check at no charge. If more time or information is needed, we continue only after you agree a new scope and delivery time. A completed check includes the tested image digest, the checks and output, and what we did not check. If a fix is needed, it also includes the exact change and output from testing that change against the same starting image. If we cannot verify a needed fix, you pay nothing.
$99 in US dollars per agreed image or described stack, whether or not it needs a fix. You pay after you get the completed result, within 14 days, through a Stripe link we send with it. If we cannot complete the agreed check, you pay nothing. For more than one image, we agree the image count and total price with you before running.
Email hello@cybernative.ai with the subject "Canada check". Send product names and versions only, not passwords, tokens, keys, customer data, configuration files or private links. We cannot check managed services, private registries or Windows images. See our Terms and Privacy.
Which releases are still wrong
The correct offsets from 1 November 2026 are Vancouver UTC−07, Edmonton and Inuvik UTC−06, and Winnipeg UTC−05. In Morocco (Africa/Casablanca) it has been UTC+00 since 20 September.
| Platform, newest releases on 14 Oct | Where its rules come from | Wrong now | Wrong from 1 Nov | Fixed release | Tested fix |
|---|---|---|---|---|---|
| MongoDB 9.0.4, 8.0.34, 7.0.45 (28 Oct) | built into the server | Morocco | Vancouver, Edmonton, Inuvik, Winnipeg | none announced | --timeZoneInfo with 2026e zoneinfo |
| Elasticsearch 9.5.5, 8.19.23 | the bundled JDK's tzdb.dat (2026b) | Morocco | Edmonton, Inuvik, Winnipeg | 9.5.6, 9.4.9 and 8.19.24, released on 2 November (2026e) | replace tzdb.dat |
| OpenSearch 3.9.0 / 2.19.7 (28 Oct) | the bundled JDK's tzdb.dat (2026b) | Morocco | Edmonton, Inuvik, Winnipeg (2.19.6 also Vancouver) | none announced | same as Elasticsearch |
| Trino 484 (28 Oct) | Joda-Time 2.15.0 (2026e) and the bundled JDK (2026b) | Morocco | Edmonton, Inuvik, Winnipeg | none yet; the development branch moved to a 2026e JDK on 26 October | replace the JDK's copy |
| Trino 483 | Joda-Time 2.14.2 (2026b) and the bundled JDK (2026a) | Morocco | Vancouver, Edmonton, Inuvik, Winnipeg | 484 fixes Vancouver only | replace both copies |
| DuckDB 1.5.6 | ICU built into the library (2026d) | — | Winnipeg | 2.0.0, released on 21 October (2026e); no 1.5.x fix | ICU_TIMEZONE_FILES_DIR |
| DuckDB 1.4.5 (long-term support) | ICU built into the library | Morocco | Vancouver, Edmonton, Inuvik, Winnipeg | none (the backport was declined) | same as 1.5.6 |
| ClickHouse 26.9.18.11, 26.3.50.11 | built into the server | — | none | already fixed | none needed |
ClickHouse 25.8, which is out of support, has old rules and ignores the operating system's copy. Moving to a supported release fixes it.
Our container census checks the official Docker images too: on their 14 October builds, mongo, elasticsearch, postgres and mariadb carry a time-zone copy that gives the wrong time for Canadian zones. ClickHouse's own 26.9.18.11 and 26.3.50.11 images carry the new rules. Docker's official-images copy, clickhouse:latest, was still 26.9.13.15 on 14 October, a build from before the fix.
Check and fix: MongoDB
Aggregation operators that take a timezone, such as $dateToString, $dateTrunc and $hour, use the server's rules; we tested $dateToString. Unless mongod is started with --timeZoneInfo, those rules are compiled into the server, and the official images don't set it.
Check. In mongosh:
db.aggregate([{$documents: [{}]}, {$project: {winnipeg: {$dateToString: {date: ISODate("2026-12-15T12:00:00Z"), format: "%H:%M %z", timezone: "America/Winnipeg"}}, casablanca: {$dateToString: {date: ISODate("2026-10-13T12:00:00Z"), format: "%H:%M %z", timezone: "Africa/Casablanca"}}}}])Stock mongo:8.0 prints winnipeg: '06:00 -0600', casablanca: '13:00 +0100'. Correct is 07:00 -0500 and 12:00 +0000. MongoDB 9.0.4 and 7.0.45 give the same answers as 8.0.34.
Fix. Point mongod at a 2026e zoneinfo directory. Alpine's tzdata package carries 2026e. On each server, or on any machine with Docker before you copy the directory over:
sudo mkdir -p /opt/zoneinfo-2026e
docker run --rm alpine:3.22 sh -c 'apk add -q --no-cache tzdata && tar -C /usr/share/zoneinfo -c .' | sudo tar -C /opt/zoneinfo-2026e -x
sudo chmod -R a+rX /opt/zoneinfo-2026e
TZDIR=/opt/zoneinfo-2026e TZ=America/Winnipeg date -d '2026-12-15 12:00Z' +%H:%MThe last line prints 07:00 if the copy is current. Then start mongod with --timeZoneInfo /opt/zoneinfo-2026e, or set it in mongod.conf:
processManagement:
timeZoneInfo: /opt/zoneinfo-2026eWith the official image, mount the directory and pass the option:
docker run -d --name mongo -v /opt/zoneinfo-2026e:/opt/zoneinfo-2026e:ro mongo:8.0 --timeZoneInfo /opt/zoneinfo-2026eRestart each member of a replica set the same way. After the restart, the check gives the correct answers on 9.0.4, 8.0.34 and 7.0.45.
The directory must be readable by the user mongod runs as. If it isn't, mongod won't start, logging failed to load time zone database. Use the operating system's /usr/share/zoneinfo only if the date line above, run with TZDIR=, prints 07:00. On 14 October Debian's and Ubuntu's copies were 2026c, and with them MongoDB still showed Inuvik at −07 and Winnipeg at −06. Updates with 2026e are now out for Debian 12 and 13 and Ubuntu 22.04, 24.04 and 26.04, so an updated host may pass; the date line tells you.
When to remove it. MongoDB's ticket SERVER-132098, opened on 23 July, updates the built-in rules only to 2026c and has no fix version. Keep the option until a release carries 2026e. Don't let the directory go stale when later time-zone releases come out.
Check and fix: Elasticsearch and OpenSearch
Both look up time zones in the tzdb.dat file of the JDK they ship with, not in the operating system's copy. Their time_zone options (in date_histogram, range queries and the rest) use those rules.
What we saw. In a date_histogram with calendar_interval: day and time_zone: America/Winnipeg, an event at 05:30 UTC on 15 December went into the bucket 2026-12-14T. It belongs in 15 December. In Africa/Casablanca, an event at 23:30 UTC on 12 October went into 13 October today.
Check. Print the data version of the bundled JDK. In the official images:
docker exec es sh -c "head -c 16 /usr/share/elasticsearch/jdk/lib/tzdb.dat | grep -ao '20[0-9][0-9][a-z]'"Replace es with your container's name. For OpenSearch the path is /usr/. 2026e means fixed, as on Elasticsearch 9.5.6, 9.4.9 and 8.19.24; Elasticsearch 9.5.5 and OpenSearch 3.9.0 and 2.19.7 print 2026b. To check behaviour instead, run a Painless script that returns the offset:
curl -s -H 'Content-Type: application/json' localhost:9200/_scripts/painless/_execute -d '{"script":{"source":"ZonedDateTime.ofInstant(Instant.parse(\"2026-12-15T12:00:00Z\"), ZoneId.of(\"America/Winnipeg\")).getOffset().toString()"}}'{"result":"-06:00"} means old rules; -05:00 means current. On a secured cluster, use https://, your CA (--cacert) and credentials (-u elastic, or your own user).
Fix. Upgrade to Elasticsearch 9.5.6, 9.4.9 or 8.19.24. With no other change, the Painless check on 9.5.6 and 8.19.24 printed the new offset, and each of our test events landed in the right daily bucket. Get the upgrade from docker.elastic.co or Elastic's downloads: on 3 November, the elasticsearch image on Docker Hub still stopped at 9.5.5 and 8.19.23. If you can't upgrade yet, or you run OpenSearch, build a 2026e tzdb.dat with the recipe in our Java fix. It uses OpenJDK's own sources and compiler and prints a checksum you can verify: a02e3a23d67255782b11ab81070902235ab564080f0f65ffe2a989cdaa86fe89. Make the file readable by the user Elasticsearch or OpenSearch runs as (uid 1000 in the official images), then mount it over the bundled one and restart each node:
chmod 644 tzdb-2026e.dat
docker run -d --name es -v "$PWD/tzdb-2026e.dat:/usr/share/elasticsearch/jdk/lib/tzdb.dat:ro" docker.elastic.co/elasticsearch/elasticsearch:9.5.5Add your usual settings. For OpenSearch, mount it at /usr/. Restart one node and run the check before you restart the rest. If a node won't start and logs tzdb.dat (Permission denied), the file isn't readable by that user. With the file in place, the date_histogram buckets above were correct on Elasticsearch 9.5.5 and 8.19.23 and on OpenSearch 3.9.0 and 2.19.6. The Painless check printed -05:00 on 9.5.5, 3.9.0 and 2.19.6. On OpenSearch 2.19.7, released on 20 October, the file gives the bundled JDK the new offsets for Vancouver, Edmonton, Inuvik, Winnipeg and Casablanca. The file built for Java 11 to 25 also worked in the JDK 27 that Elasticsearch 9.5.5 and 8.19.23 bundle.
If you run Elasticsearch or OpenSearch with your own JDK (ES_JAVA_HOME or OPENSEARCH_JAVA_HOME), fix that JDK instead. The image or package replaces the bundled file on every upgrade, so keep the mount until a release prints 2026e. Elasticsearch 9.5.6, 9.4.9 and 8.19.24 do, and their bundled file is byte for byte the one the recipe builds, so you can drop the mount when you upgrade. OpenJDK's October source tags carry 2026e for Java 17, 21 and 25 but only 2026c for 8, 11 and 27. The Java 27.0.1.0.3 build that Elasticsearch 9.5.6 bundles carries 2026e all the same, so check the file, not the version number. Temurin 17.0.21, 21.0.13 and 25.0.5, released on 22 October, ship 2026e, but at 09:00 UTC on 23 October only for some platforms, including Linux x64, with no Windows build or official Docker image. Check the JDK you run.
Check and fix: Trino
Trino has two copies of the rules: Joda-Time's and the JDK's tzdb.dat. Functions such as hour() and format_datetime() follow Joda-Time's copy, casting to varchar follows the JDK's, and date_trunc depends on both. Both copies must match.
In 484, released on 15 October, they don't. Joda-Time 2.15.0 has 2026e, but the bundled JDK, Temurin 25.0.4, has 2026b, from April. hour() is right, and date_trunc('day', …) for a time on 15 December returns the right instant but prints it as 2026-12-14 23:00:00 America/Winnipeg. Text from the JDK's copy shows the old offset: your client's display, CAST(… AS varchar) and to_iso8601. CAST(… AS date), day(), format_datetime() and date_format() are right. Edmonton and Inuvik do the same, and Casablanca's day start already prints as 01:00. Vancouver is right in 484.
In 483 Joda-Time's copy is 2026b and the JDK's is 2026a. Neither has the Alberta, Northwest Territories or Manitoba change, so hour(at_timezone(…, 'America/Winnipeg')) for 12:00 UTC on 15 December returns 6 instead of 7. Only Joda-Time's copy has British Columbia's change, so for Vancouver hour() is already right while a cast to varchar shows the old offset.
Check:
SELECT hour(at_timezone(TIMESTAMP '2026-12-15 12:00:00 UTC', 'America/Winnipeg')), date_trunc('day', at_timezone(TIMESTAMP '2026-12-15 06:30:00 UTC', 'America/Winnipeg'));Correct is 7 and 2026-12-15 00:00:00 America/Winnipeg. Stock 484 gives 7 and 2026-12-14 23:00:00 America/Winnipeg. Stock 483 gives 6 and a midnight that prints correctly but is an hour late (06:00 UTC, not 05:00); hour() is the part that shows the error.
On 483, Vancouver already has the split:
SELECT date_trunc('day', at_timezone(TIMESTAMP '2026-12-15 07:30:00 UTC', 'America/Vancouver'));Correct is 2026-12-15 00:00:00 America/Vancouver. Stock 483 gives 2026-12-14 23:00:00 America/Vancouver. 484 gives the correct answer.
Fix on 484: replace the JDK's copy. You need only the 2026e tzdb.dat from our Java fix. Print the bundled JDK's path:
docker run --rm --entrypoint sh trinodb/trino:484 -c 'echo $JAVA_HOME'In 484 it is /usr/. Make the file readable by Trino's user, then mount it under that path on the coordinator and every worker:
chmod 644 tzdb-2026e.dat
docker run -d --name trino \
-v "$PWD/tzdb-2026e.dat:/usr/lib/jvm/jdk-25.0.4+7/lib/tzdb.dat:ro" \
trinodb/trino:484The check then gives 7 and 2026-12-15 00:00:00 America/Winnipeg, and Edmonton, Inuvik and Morocco are right. The check is worked out on the coordinator, so it passes even if a worker is missing the file. On every node, check the file itself:
docker exec <container> sh -c 'sha256sum $JAVA_HOME/lib/tzdb.dat'It should print a02e3a23d67255782b11ab81070902235ab564080f0f65ffe2a989cdaa86fe89. A file mounted under another JDK's path is ignored without an error, and this line shows it: the 483 command below changes nothing on 484. You don't need the Joda-Time steps on 484.
Fix on 483: replace both. You need the 2026e tzdb.dat from our Java fix and Joda-Time 2.15.0's compiled zones:
curl -fLO https://repo1.maven.org/maven2/joda-time/joda-time/2.15.0/joda-time-2.15.0.jar
unzip -q joda-time-2.15.0.jar 'org/joda/time/tz/data/*' -d joda-2.15.0
docker run --rm --entrypoint cat trinodb/trino:483 /etc/trino/jvm.config > jvm.config
echo '-Dorg.joda.time.DateTimeZone.Folder=/etc/trino/joda-tz' >> jvm.config
docker run --rm --entrypoint sh trinodb/trino:483 -c 'echo $JAVA_HOME'The jar's SHA-256 is 6bbe1302e5bec0f03eb7e7442334b475bb225361a5498369d6a0a9a472630c33. If you already have your own jvm.config, add the -D line to it instead. The last command prints the bundled JDK's path, /usr/ in 483. Then mount all three on the coordinator and every worker:
chmod 644 tzdb-2026e.dat
docker run -d --name trino \
-v "$PWD/tzdb-2026e.dat:/usr/lib/jvm/jdk-25.0.3+9/lib/tzdb.dat:ro" \
-v "$PWD/joda-2.15.0/org/joda/time/tz/data:/etc/trino/joda-tz:ro" \
-v "$PWD/jvm.config:/etc/trino/jvm.config:ro" \
trinodb/trino:483The check then gives 7 and 2026-12-15 00:00:00 America/Winnipeg, the Vancouver query gives 2026-12-15 00:00:00 America/Vancouver, and Morocco is right. As on 484, the check is worked out on the coordinator: run the same sha256sum line on every node. On a tarball install, the JDK is whatever you run Trino with: apply the Java fix to it, and on 483 add the -D line to etc/jvm.config. On 26 October Trino's development branch moved its image to Temurin 25.0.5, which carries 2026e. Keep the mount until a release ships with it.
Check and fix: DuckDB
DuckDB handles time zones (TIMESTAMPTZ, SET TimeZone, timezone()) with the ICU library built into it. It doesn't read the operating system's copy: mounting 2026e zoneinfo changed nothing.
Check. In the DuckDB CLI or any client:
SELECT strftime(timezone('America/Winnipeg', TIMESTAMPTZ '2026-12-15 12:00:00+00'), '%H:%M') AS winnipeg, strftime(timezone('Africa/Casablanca', TIMESTAMPTZ '2026-10-13 12:00:00+00'), '%H:%M') AS casablanca;Correct is 07:00 and 12:00. DuckDB 1.5.6 gives 06:00 and 12:00; 1.4.5 gives 06:00 and 13:00.
Fix. ICU loads newer time-zone data from a directory named in ICU_TIMEZONE_FILES_DIR. Download ICU's 2026e files from the Unicode Consortium's icu-data repository:
mkdir -p icu-tz-2026e
for f in zoneinfo64 timezoneTypes metaZones windowsZones; do curl -fsSL -o icu-tz-2026e/$f.res https://raw.githubusercontent.com/unicode-org/icu-data/main/tzdata/icunew/2026e/44/le/$f.res; done
sha256sum icu-tz-2026e/*.resExpected checksums:
5b484c7f02c99d5164208ce84e18fba67c6314d77cf60503e2b19f708b66c6da icu-tz-2026e/metaZones.res
5e77ce5afb7374a36cbe3be197d0a6deaa919e6f672c2a372f7a9d91b7f8534f icu-tz-2026e/timezoneTypes.res
b8c3a7adb94fd659f8203ee4af4dc72a4e6b14566baac1855c493096f337184b icu-tz-2026e/windowsZones.res
5a168fb78cccfc872f9a50e91facf0bf8b7204a6c4f92fe5c64a8165e9e62448 icu-tz-2026e/zoneinfo64.resSet the variable in the environment that starts the process, with an absolute path:
export ICU_TIMEZONE_FILES_DIR=/path/to/icu-tz-2026eWith it, the check gives 07:00 and 12:00 on 1.5.6 and 1.4.5 in Python, and in the 1.5.6 CLI. Setting os.environ inside Python after import duckdb has no effect, even before the first time-zone query. To check that the files change nothing else, we compared all 638 zones at five instants with and without them. Only the zones named in the time-zone release notes changed.
Or upgrade. DuckDB 2.0.0, released on 21 October, carries 2026e. It is a major release, and we haven't tested it. The maintainers decided not to put 2026e in another 1.4 or 1.5 release.
When to remove it. Once you run a release that carries 2026e or later, unset the variable so these files don't hold back later updates.
What we did not check
- Managed services: MongoDB Atlas, Elastic Cloud, Amazon OpenSearch Service, Starburst Galaxy, MotherDuck and ClickHouse Cloud run their own builds.
- arm64, and installs from deb or rpm packages. These should use the same built-in data as the images, but we didn't run them.
- Trino from the tarball: we ran only its official images.
- DuckDB 2.0.0, and DuckDB's Node.js, R and JDBC clients, which use the same library.
- Whether an OpenSearch release after 3 November has a 2026e JDK. On 3 November, OpenSearch 3.9.0 and 2.19.7 were still the latest in their lines. On Elasticsearch 9.4.9 we ran only the version check.
- Kibana and OpenSearch Dashboards, which send their own time-zone setting with each query.
Sources
- IANA time zone database release 2026e and earlier releases' notes for each change.
- MongoDB: SERVER-132098, "Upgrade timelib and timezone data files to 2026c", and the
processManagement.configuration option.timeZoneInfo - Trino: the 484 release notes, which list no time-zone data change; the
trinodb/image (Temurin 25.0.4+7, Joda-Time 2.15.0); the development branch's commit Update JDK to jdk-25.0.5+8; and our report of the two copies, trinodb/trino#31590.trino:484 - DuckDB pull requests #26297 (2026e, merged for 2.0), #26299 and #26302 (1.5 and 1.4 backports, closed).
- ICU time-zone data: unicode-org/icu-data.
- ClickHouse supported versions.
- OpenJDK's time-zone data version at the October tags: jdk-21.0.13-ga (2026e, as for 17 and 25) and jdk-27.0.1-ga (2026c). The Java 27.0.1.0.3 build in Elasticsearch 9.5.6, 9.4.9 and 8.19.24 carries 2026e: we read the bundled time-zone file in Elastic's images and in the 9.5.6 and 8.19.24 tarballs.
- Our runtimes guide for the
tzdb.datrecipe and the Alpine zoneinfo copy.
Hit by the 1 November change? We can check your image: US$99, pay after you get the result. Email hello@cybernative.ai, subject "Canada check".