Skip to content

Africa/Casablanca and Africa/El_Aaiun still resolve to UTC+01 after the 2026-09-20 switch (embedded tzdata predates IANA 2026c) #7256

Description

@vahidshaik1901

Summary

workerd's embedded tzdata is older than IANA 2026c, so Africa/Casablanca and Africa/El_Aaiun still resolve to UTC+01 for instants on or after 2026-09-20T01:00:00Z. The correct offset from that instant is UTC+00.

The transition is 14 days away. It is a permanent change to plain UTC, not a seasonal one, so every Worker that renders a wall-clock time for Morocco or Western Sahara will be an hour late from 2026-09-20 onward, indefinitely.

Why this is easy to miss

The failure is silent. Date instants stay correct — only the wall-clock label is wrong — so responses look plausible and nothing throws. In our case, maghrib for 18:34Z rendered as 19:34 local instead of 18:34.

It also does not reproduce under some local toolchains. Bun already carries 2026c, so our unit tests and validation harness passed while production was wrong.

Reproduction

import { Miniflare } from "miniflare";

const script = `
export default { async fetch() {
  const fmt = (d, tz) => new Intl.DateTimeFormat("en-GB", {
    timeZone: tz, timeZoneName: "longOffset"
  }).formatToParts(new Date(d)).find(p => p.type === "timeZoneName").value;
  return Response.json({
    before_casablanca: fmt("2026-09-19T12:00:00Z", "Africa/Casablanca"),
    after_casablanca:  fmt("2026-09-25T12:00:00Z", "Africa/Casablanca"),
    after_el_aaiun:    fmt("2026-09-25T12:00:00Z", "Africa/El_Aaiun"),
  });
}};`;

const mf = new Miniflare({ modules: true, script, compatibilityDate: "2026-08-01" });
console.log(await (await mf.dispatchFetch("http://x/")).json());
await mf.dispose();

Observed on workerd 1.20260906.1 (also on 1.20260730.1, and reported against production Workers on 2026-08-25):

{
  "before_casablanca": "GMT+01:00",
  "after_casablanca":  "GMT+01:00",
  "after_el_aaiun":    "GMT+01:00"
}

Expected, per 2026c:

{
  "before_casablanca": "GMT+01:00",
  "after_casablanca":  "GMT",
  "after_el_aaiun":    "GMT"
}
Instant (UTC) workerd 1.20260906.1 Expected (2026c)
2026-09-19T12:00:00Z +01:00 +01:00
2026-09-20T00:00:00Z +01:00 +01:00
2026-09-20T02:00:00Z +01:00 +00:00
2026-10-15T12:00:00Z +01:00 +00:00
2026-12-01T12:00:00Z +01:00 +00:00

Source for the rule

  • IANA tzdb 2026c, from the [PROPOSED] Morocco goes to plain UTC on 2026-09-20 thread on tz@iana.org (Paul Eggert, 2026-07-04).
  • Morocco's National Telecommunications Regulatory Agency posted to the same list.
  • Moroccan Decree 2.26.530.

Both Africa/Casablanca and Africa/El_Aaiun are covered by the decree, and both are affected here.

Impact

Anything that formats a Moroccan wall-clock time in a Worker: scheduling, calendar exports, business-hours logic, prayer times. Because Date instants remain correct, existing tests that compare instants will not catch it — only tests that assert on rendered local time will.

What we did meanwhile

We added a runtime-conditional override that formats Casablanca/El_Aaiun instants at or after 2026-09-20T01:00:00Z in UTC, but only while the runtime disagrees, so it disables itself once the embedded tzdata catches up. Happy to share that if useful, though the real fix is the tzdata bump.

Please let me know if a minimal repro repo would help.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions