Calcard 0.4 renumbered time zone ids, so stored zones change meaning after the upgrade

Issue Description

Stalwart stores time zones as calcard’s numeric id (Tz::as_id) in a few places: the calendar default time zone, the start and end zone of each event’s time range, and queued alarms. calcard 0.4, which the v1.0.0 branch uses, numbers the zones differently from 0.3, so anything 0.16 wrote will point at a different zone when 1.0 reads it.

Expected Behavior

a zone id stored by 0.16 means the same zone on 1.0.

Actual Behavior

106 of the 597 ids are off by one. UTC is 592 in calcard 0.3, and 592 is US/Samoa in 0.4. So a calendar whose default zone is UTC would show US/Samoa, and alarms and event ranges stored with UTC would be computed in UTC-11.

Some others:
UTC 592 → US/Samoa
Pacific/Honolulu 544 → Pacific/Guam
US/Pacific 590 → US/Mountain
GMT 493 → GB-Eire
Zulu 596 → WET

Ids 0 to 490 are unchanged (Africa, America, Asia, Europe, Etc), so Europe/Berlin or America/New_York are fine.

Reproduction Steps

1 Build a small program against calcard 0.3.14 (the version in v0.16.23) and one against calcard 0.4 at 39595194 (the version the v1.0.0 branch builds with).
2 In each, print Tz::from_id(id) for every id.
3 Compare the two lists. They are identical up to 490. At 491 calcard 0.4 has “Factory”, and every zone after it moves up by one.

Relevant Log Output

calcard 0.3.14: 592 UTC
calcard 0.4.0: 592 US/Samoa
calcard 0.4.0: 593 UTC

Stalwart Version

v0.16.x

Installation Method

Built from source

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

Internal

Additional Context

the new ids come from src/common/tzdb.rs in calcard (“Factory” is on line 513), added in e75b9e5 “Migrate to jiff”. The comment at the top of that file says entries are never reordered or removed, only appended, but compared to 0.3 one was inserted in the middle.

Moving “Factory” to the end of the list (after “posixrules”) brings back all 597 old ids exactly, I checked the two tables against each other. UTC_ID would go back to 592. That seems simpler than remapping ids in the migration.

On the Stalwart side the ids are stored in crates/groupware/src/calendar/mod.rs (Timezone::IANA(u16) on line 396, ComponentTimeRange start_tz/end_tz on lines 365-366) and in the alarm tasks (alarm.rs, lines 123-125).

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

This is a bug report, not a documentation question, and it’s already been thoroughly investigated by the user with a specific technical fix identified. This doesn’t need further doc research from me; it needs to go to the maintainers as a genuine bug report.

I’ll confirm there’s nothing in the docs addressing this migration behavior, then respond appropriately.

No relevant docs found on this bug — this is a genuine issue report, not a documentation question. I’ll respond acknowledging it as an issue report rather than trying to answer as documentation.

This is a well-documented bug report rather than a documentation question, so there is nothing in current docs to confirm or deny here. This looks like a genuine data-correctness issue worth a maintainer’s direct attention given the concrete repro steps and precise diagnosis (calcard 0.4’s insertion of “Factory” mid-table shifting all subsequent Tz ids by one, versus 0.3’s numbering). I don’t have authority to confirm the fix approach, so I won’t speculate on Stalwart’s behalf.

This isn’t covered in the current docs. A community member or staff member will follow up.

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

This is not a bug, it’s a semver breaking change.

Forgot to mention: v1.0.0 will include a migration tool for this breaking change as well as many others. Thanks for the report anyway.

Sounds good, thank you for the fast answers and fixes