Mugo Web main content.

Time zone databases, and how permanent daylight savings changed event times

By: Peter Keung | September 28, 2026 | Tales from a Developer and development

In Canada and the US, the vast majority of provinces, states, and territories observe daylight savings time. We are scheduled to change our clocks on Sunday, November 1, 2026, falling back by 1 hour at 2:00am.

However, on March 2 of this year, the province of British Columbia decided not to observe any more time changes starting on November 1, staying on permanent daylight savings time. On June 18, Alberta made the same decision. And most recently, on September 17th, Manitoba decided to follow this precedent and will likewise stay on daylight savings permanently, starting this November. 

This created some work for content editors and website developers in those provinces, and what should have been a simple update ended up requiring some investigation. Here's the story of why event calendars started to display the wrong time for events, and how we fixed it.

tzdata: the time zone database

Most of our clients' websites run on Ubuntu. This means that our servers use tzdata, otherwise known as the time zone database. If you run this command on the server, you'll see an output of all scheduled time zone changes in Alberta:

$ zdump -v America/Edmonton Sun Nov  2 07:59:59 2025 UT = Sun Nov  2 01:59:59 2025 MDT isdst=1 gmtoff=-21600 Sun Nov  2 08:00:00 2025 UT = Sun Nov  2 01:00:00 2025 MST isdst=0 gmtoff=-25200 Sun Mar  8 08:59:59 2026 UT = Sun Mar  8 01:59:59 2026 MST isdst=0 gmtoff=-25200 Sun Mar  8 09:00:00 2026 UT = Sun Mar  8 03:00:00 2026 MDT isdst=1 gmtoff=-21600 Sun Nov  1 07:59:59 2026 UT = Sun Nov  1 01:59:59 2026 MDT isdst=1 gmtoff=-21600 Sun Nov  1 08:00:00 2026 UT = Sun Nov  1 01:00:00 2026 MST isdst=0 gmtoff=-25200 Sun Mar 14 08:59:59 2027 UT = Sun Mar 14 01:59:59 2027 MST isdst=0 gmtoff=-25200 Sun Mar 14 09:00:00 2027 UT = Sun Mar 14 03:00:00 2027 MDT isdst=1 gmtoff=-21600 [...] Sun Mar  8 08:59:59 2499 UT = Sun Mar  8 01:59:59 2499 MST isdst=0 gmtoff=-25200 Sun Mar  8 09:00:00 2499 UT = Sun Mar  8 03:00:00 2499 MDT isdst=1 gmtoff=-21600 Sun Nov  1 07:59:59 2499 UT = Sun Nov  1 01:59:59 2499 MDT isdst=1 gmtoff=-21600 Sun Nov  1 08:00:00 2499 UT = Sun Nov  1 01:00:00 2499 MST isdst=0 gmtoff=-25200

The above output was from before the time zone database was updated, and you can see that the schedule goes all the way to the year 2499!

If you run that command now, you should see the following, indicating that the time zone offset (relative to UTC) will no longer change in November.

$ zdump -v America/Edmonton Sun Nov  2 07:59:59 2025 UT = Sun Nov  2 01:59:59 2025 MDT isdst=1 gmtoff=-21600 Sun Nov  2 08:00:00 2025 UT = Sun Nov  2 01:00:00 2025 MST isdst=0 gmtoff=-25200 Sun Mar  8 08:59:59 2026 UT = Sun Mar  8 01:59:59 2026 MST isdst=0 gmtoff=-25200 Sun Mar  8 09:00:00 2026 UT = Sun Mar  8 03:00:00 2026 MDT isdst=1 gmtoff=-21600 Sun Nov  1 07:59:59 2026 UT = Sun Nov  1 01:59:59 2026 MDT isdst=1 gmtoff=-21600 Sun Nov  1 08:00:00 2026 UT = Sun Nov  1 02:00:00 2026 CST isdst=0 gmtoff=-21600

A quick side note: if you were using the America/Los_Angeles or America/Denver identifier in your code for a BC or Alberta time zone, you'd better update your settings!

The problem: unwanted event time changes

Consider the following event poster, handed out to potential attendees at your Alberta-based library or posted on a bulletin board:

Teddy Bear Yoga poster. Shows cartoon bears trying different yoga poses. Lists the date and time as November 15th, 1pm.

This event, Teddy Bear Yoga, takes place on November 15 at 1:00pm. Whether or not the time zone is about to change in November by 1 hour or not at all, people expect the event to happen that day at 1:00pm.

Teddy Bear Yoga was planned well in advance, so you entered it into your website content management system in early June:

Date configuration from the backend showing an event held on 11-15-2026 at 13:00

This date and time is stored as a UNIX timestamp,  which in early June, would have been calculated as 1794772800:

# Before the tzdata update $ php -r "print strtotime( 'November 15, 2026 1:00pm' );" 1794772800

But something shocking happened when you loaded the event in July: the time changed!

Backend date configuration showing event day 11-15-2026 at 14:00

Despite the province deciding there would be no more time changes, you now have an unexplained time change on your hands! If you output that timestamp now, you'll see that it shows as 2:00pm, even though nobody had edited the event:

<?php print "\n"; $ts = 1794772800; print "tzdata:\n"; print (new DateTimeImmutable('@'.$ts)) ->setTimezone(new DateTimeZone('America/Edmonton')) ->format('Y-m-d H:i:s P T'); print "\n\n";

tzdata: 2026-11-15 14:00:00 -06:00 CST

On the front-end of the website, we had something even more confusing. The events calendar was displaying the wrong time:

Snapshot of program information from a different part of the website. Lists the time for Teddy Bear Yoga as 2-3pm

… but the event page itself was displaying the correct time:

Snapshot of the event information display, showing Teddy Bear Yoga happening at 74 Mackenzie Street, Lethbridge, Main Branch, at 1:00 PM - 2:00 PM

We'll get to the event page problem in the next section, but why was the back-end and events calendar showing the wrong time? A computer's logic considers this the right time, because the timestamp 1794772800 used to mean 1:00pm according to the old timezone rules, but it now means 2:00pm according to the new timezone rules. 1:00pm in the new timezone rules is actually represented by a different timestamp:

# After the tzdata update $ php -r "print strtotime( 'November 15, 2026 1:00pm' );" 1794769200

Extra headache: another time zone database

Let's come back to the event page, which was still showing 1:00pm:

Snapshot of the event information display, showing Teddy Bear Yoga happening at 74 Mackenzie Street, Lethbridge, Main Branch, at 1:00 PM - 2:00 PM

This appears to be correct, but is actually incorrect. Our Twig template code on that page uses the format_datetime() function:

{{ event.start.timestamp|format_datetime(locale=app.request.locale, pattern="h:mm aaa") }}

… and that function uses the ICU (International Components for Unicode) library, which has its own time zone database! That database has not been updated in a stock install of Ubuntu 24.

You can compare the output of a tzdata-formatted time and an ICU-formatted time as follows:

<?php print "\n"; $ts = 1794772800; print "tzdata:\n"; print (new DateTimeImmutable('@'.$ts)) ->setTimezone(new DateTimeZone('America/Edmonton')) ->format('Y-m-d H:i:s P T'); print "\n\n"; print "ICU:\n"; print (new IntlDateFormatter( 'en_CA', IntlDateFormatter::NONE, IntlDateFormatter::NONE, 'America/Edmonton', IntlDateFormatter::GREGORIAN, 'yyyy-MM-dd HH:mm:ss Z z' ))->format($ts); print "\n\n";

This confirms our problem:

tzdata: 2026-11-15 14:00:00 -06:00 CST ICU: 2026-11-15 13:00:00 -0700 MST

The fix: what appears wrong is right, and what appears right is wrong

Our fix consisted of 2 parts: updating the code and manually reviewing all events that occurred after November 1, 2026.

Regarding the code, we created a new Twig function format_php_datetime() that is backwards compatible with format_datetime():

{{ event.start.timestamp|format_php_datetime(locale=app.request.locale, pattern="h:mm aaa") }}

… but it manually calculates the time zone offset:

// Express wall-clock as a UTC timestamp so ICU cannot re-apply zone rules $wallClockUtcTs = $dt->getTimestamp() + $dt->getOffset(); $formatter = new IntlDateFormatter(     Locale::getDefault(),     IntlDateFormatter::NONE,     IntlDateFormatter::NONE,     'UTC',     IntlDateFormatter::GREGORIAN,     $pattern ); $formatted = $formatter->format( $wallClockUtcTs );

We could have alternatively installed the "tzdata-icu" package, which tells ICU to source its time zone database from tzdata:

sudo apt install tzdata-icu

Now that the events were displaying consistent times across the different parts of the site, Teddy Bear Yoga was now universally displaying the wrong time of 2:00pm. We thought of creating a script to update all affected events. Such a script would have to consider at least the following:

  • The boundary of dates for the affected events since only "standard time" time periods would be affected: between Nov X? 2026 and Mar X? 2027, between Nov X? 2027 and Mar X? 2028, between Nov X? 2028 and Mar X? 2029, and so on.
  • Which events to update. Events published before the time zone database was updated would be affected, but is that reliable? What if an editor had noticed the difference and already made the fix? We could exclude events that had since been modified, but what if an editor had edited something else about the event and not the time?
  • Event recurrence rules. Our system stores recurring event occurrences as time rules, not individual timestamps. So only recurring events with their first occurrence within "standard time" time periods would be affected.

Since a script's results would still have to be manually and carefully reviewed by editors, we decided that it was most reliable to not involve a script at all, and just have editors review all events occurring after November 1.

It's coming for us all

With the problem solved for affected BC and Alberta websites, it's a good time to start preparing in advance for other websites. After all, the USA is working towards permanent daylight savings time, which will likely spur other provinces like Ontario to do the same. Ontario already passed such an Act contingent on Quebec and New York joining in.

(A last note: digital skeptics might notice that no change is required to the printed event posters. Analog has its benefits!)