How to select zones for a TimeZone picker
Hi all, I'm building a TimeZone picker with the following constraints: 1. At least one distinct timezone per country (so that e.g. there is an entry for Atlantic/Reykjavik instead of mapping IS to Africa/Abidjan) 2. Within a country, do not show timezones that currently have identical rules to another timezone in the same country (i.e. historical differences don't matter). Because of (1) I started from zone.tab rather than zone1970.tab. However, I'm not sure how to handle (2). For example, Spain has three zones in zone.tab: Europe/Madrid, Africa/Ceuta, and Atlantic/Canary. But as far as most users are concerned, as of today there are only two timezones in Spain: Madrid and Canary Islands. Ceuta follows Madrid rules, so there should be no need to show this as an option to the user. Another example: the U.S. lists 29 zones, but only 8 are distinct today (ignoring historical changes). So, the question: Any suggestions on how to filter timezones within each country to drop those that as of today are not relevant except for historical differences? Thank you, Guillermo Rodriguez Garcia guille.rodriguez@gmail.com
On 11/2/25 03:11, Guillermo Rodriguez Garcia via tz wrote:
...
So, the question: Any suggestions on how to filter timezones within each country to drop those that as of today are not relevant except for historical differences? ...
The last line of each timezone definition appears to contain the current POSIX definition. (I don't know where this is documented.) If those lines are identical, might zones be merged? -- gil
HI Guillermo - I think what you're looking for is the algorithm defined in the JavaScript Internationalization (ECMA-402) specification. Specifically, the AvailableNamedTimeZoneIdentifiers <https://tc39.es/ecma402/#sup-availablenamedtimezoneidentifiers> abstract operation. This algorithm enumerates through all time zones, ensuring at least one time zone per country while removing outdated intra-country links like America/Montreal that have had the same time zone history since 1970 as other zones. I wrote the section of the specification linked above, so I know it pretty well and am happy to answer questions about it. Note that this algorithm wasn't a new thing; it simply reverse-engineers and provides formal spec language for the existing rules that CLDR (the internationalization data source used by JavaScript, Java, and more) has used for 10+ years when deciding which zones to enumerate and which to omit. Note that as of today, only Firefox actually follows this specification exactly. Chrome (using the V8 JavaScript engine) and Safari/iOS/MacOS (using the JavaScriptCore JS engine) will be adopting it in 2026 when their implementations are complete. There are polyfills <https://github.com/tc39/proposal-temporal?tab=readme-ov-file#polyfills> available that provide JS code that does implement the spec on any JS engine today, including V8 and JSC. If you're writing in C++, then you can also use the icu::TimeZone::getIanaID() <https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/classicu_1_1TimeZone...> function in the Unicode ICU library, combined with the enumeration function in the same class. I believe there's also a Java version of this API. Finally, you can get the data directly from CLDR here: https://github.com/unicode-org/cldr/blob/main/common/bcp47/timezone.xml. Make sure to use the iana attribute for each element so that you get the most up-to-date aliases instead of outdated ones like Asia/Calcutta or Europe/Kiev. BTW, this is the data source used in the ICU API above. Hopefully, one of these resources can be helpful for you. Thanks, Justin On Mon, Nov 3, 2025 at 10:13 AM Guillermo Rodriguez Garcia via tz < tz@iana.org> wrote:
Hi all,
I'm building a TimeZone picker with the following constraints:
1. At least one distinct timezone per country (so that e.g. there is an entry for Atlantic/Reykjavik instead of mapping IS to Africa/Abidjan)
2. Within a country, do not show timezones that currently have identical rules to another timezone in the same country (i.e. historical differences don't matter).
Because of (1) I started from zone.tab rather than zone1970.tab. However, I'm not sure how to handle (2).
For example, Spain has three zones in zone.tab: Europe/Madrid, Africa/Ceuta, and Atlantic/Canary. But as far as most users are concerned, as of today there are only two timezones in Spain: Madrid and Canary Islands. Ceuta follows Madrid rules, so there should be no need to show this as an option to the user.
Another example: the U.S. lists 29 zones, but only 8 are distinct today (ignoring historical changes).
So, the question: Any suggestions on how to filter timezones within each country to drop those that as of today are not relevant except for historical differences?
Thank you,
Guillermo Rodriguez Garcia guille.rodriguez@gmail.com
Hi Paul, El lun, 3 nov 2025 a las 19:23, Paul Gilmartin via tz (<tz@iana.org>) escribió:
On 11/2/25 03:11, Guillermo Rodriguez Garcia via tz wrote:
...
So, the question: Any suggestions on how to filter timezones within each country to drop those that as of today are not relevant except for historical differences? ...
The last line of each timezone definition appears to contain the current POSIX definition. (I don't know where this is documented.) If those lines are identical, might zones be merged?
Yes. Although my question was not really "what zones can be merged" (I already solved that -- I can already identify zones which have identical rules for "present and future times"). The real question was: whenever I find two zones that can be merged, which one wins? For example, in the case I mentioned in my original email (Spain), Ceuta should be discarded and Madrid should be kept. Thanks, Guillermo Rodriguez Garcia guille.rodriguez@gmail.com
On 2025-11-02 02:11, Guillermo Rodriguez Garcia via tz wrote:
how to filter timezones within each country to drop those that as of today are not relevant except for historical differences?
For each country listed in zone.tab, if at least one of its timezones appear in zonenow.tab, drop its timezones that do not appear there. Although this won't be "perfect" it should be good enough (and opinions will differ about what is "perfect").
Alas, that last line applies to times after time zone rules have been exhausted; if differing rules extend in to the future, the zones may not be the same at present. @dashdashado On Mon, Nov 3, 2025, 1:23 PM Paul Gilmartin via tz <tz@iana.org> wrote:
On 11/2/25 03:11, Guillermo Rodriguez Garcia via tz wrote:
...
So, the question: Any suggestions on how to filter timezones within each country to drop those that as of today are not relevant except for historical differences? ...
The last line of each timezone definition appears to contain the current POSIX definition. (I don't know where this is documented.) If those lines are identical, might zones be merged?
-- gil
Hi Paul, El lun, 3 nov 2025 a las 19:48, Paul Eggert (<eggert@cs.ucla.edu>) escribió:
On 2025-11-02 02:11, Guillermo Rodriguez Garcia via tz wrote:
how to filter timezones within each country to drop those that as of today are not relevant except for historical differences?
For each country listed in zone.tab, if at least one of its timezones appear in zonenow.tab, drop its timezones that do not appear there. Although this won't be "perfect" it should be good enough (and opinions will differ about what is "perfect").
Not sure if that will help much; zonenow.tab has a very limited set of timezones, so for many countries, the precondition "if at least one of its timezones appear in zonenow.tab" will not be met. For example in the case of Spain (the example in my original email), I have three zones: - Europe/Madrid - Atlantic/Canary - Africa/Ceuta But none of them appears in zonenow.tab. Same with many European countries (I am mentioning European countries just because these are the ones I am more familiar with, there's nothing specific about Europe here) BR, Guillermo Rodriguez Garcia guille.rodriguez@gmail.com
El lun, 3 nov 2025 a las 19:43, Justin Grant (<justingrant.ietf.public@gmail.com>) escribió:
HI Guillermo - I think what you're looking for is the algorithm defined in the JavaScript Internationalization (ECMA-402) specification. Specifically, the AvailableNamedTimeZoneIdentifiers abstract operation.
This algorithm enumerates through all time zones, ensuring at least one time zone per country while removing outdated intra-country links like America/Montreal that have had the same time zone history since 1970 as other zones.
I would actually need something similar to this, but instead of removing "outdated intra-country links that have had the same time history since 1970 as other zones", I would want to remove zones that have the same rules for present and future times. With the algorithm linked above I still get many zones where the only differences are historical (for example Africa/Ceuta and Europe/Madrid)
If you're writing in C++, then you can also use the icu::TimeZone::getIanaID() function in the Unicode ICU library, combined with the enumeration function in the same class. I believe there's also a Java version of this API.
Yes, I am using already ICU4J to detect zones for the same country and which have identical rules for present and future times. The only missing bit is, when I find such cases, which one wins :-)
Finally, you can get the data directly from CLDR here: https://github.com/unicode-org/cldr/blob/main/common/bcp47/timezone.xml. Make sure to use the iana attribute for each element so that you get the most up-to-date aliases instead of outdated ones like Asia/Calcutta or Europe/Kiev. BTW, this is the data source used in the ICU API above.
Yes, but this has the same problem: It lists zones which have identical rules for present and future times and only differ in their history (again: Africa/Ceuta and Europe/Madrid) Thanks, Guillermo Rodriguez Garcia guille.rodriguez@gmail.com
On 2025-11-03 10:53, Guillermo Rodriguez Garcia wrote:
zonenow.tab has a very limited set of timezones, so for many countries, the precondition "if at least one of its timezones appear in zonenow.tab" will not be met.
Oh, good point. I was trying to come up with something simple but evidently it needs to be trickier. Here's an idea. Make the following change to Makefile: --- a/Makefile +++ b/Makefile @@ -1036,7 +1036,7 @@ now.ck: checknow.awk date tzdata.zi zdump zic zone1970.tab zonenow.tab $(AWK) \ -v zdump_table=$@d/zdump-1970.tab \ -f checknow.awk - rm -fr $@d + : rm -fr $@d touch $@ tables.ck: checktab.awk $(YDATA) backward zone.tab zone1970.tab and then run "make now.ck". Then look at now.ckd/zdump-now.tab to decide whether two timezones have equivalent behavior from now on. Just as a warning, if you do this next week you may get a different answer from today, even if tzdata doesn't change. This is because the contents of now.ckd/zdump-now.tab must of course depend on the current time.
On Mon, 3 Nov 2025 at 13:48, Paul Eggert via tz <tz@iana.org> wrote:
Although this won't be "perfect" it should be good enough (and opinions will differ about what is "perfect").
…and that gets into an understated subtlety that I see folks often forgetting about when attempting to balance the laudable goal of simplifying UX against the true complexities of civil timekeeping. Of course, most people and end-users only think about "time zones" in a colloquial sense, if at all — ranging from coarse definitions ("where does the time match now?") to some that are reasonably finer ("where does the time match now and into the future?"). But everyday applications generally do ultimately need to store and display *some* information about the past in addition to information about the present and future. As such, any algorithmic simplification of the full zone set will inevitably fail someone or something for *some purpose*, because how you decide what to include and what to shed will vary. (Indeed, extrapolating this — our 1970 cutoff surely frustrates many, but is a long-standing compromise borne out of practicality.) As an illustrative, but extreme and contrived example — If an entire continent were to suddenly agree to unify all of its timezones tomorrow, I would imagine that a great deal of folks would absolutely insist that their apps still need to care about at least the recent history of timekeeping throughout that area. It would be fairly reasonable for developers to want their apps to retain and properly reference that recent historical data for quite some time to come — for some, perhaps even for a duration approximating "forever". More realistically and more nuanced — Kazakhstan's two "time zones" (in the colloquial sense) were merged about 20 months ago. Does your application still need to care about the deeper timekeeping history there? Maybe! If so, should you keep it around for another year? Five? Twenty? I don't know! And no algorithm, however well-designed, will ever *truly* be able to decide these things for you unless you can provide it with additional information about your specific priorities. I'd imagine a developer of apps where Kazakhstan is a key demographic would be likely to answer very differently than someone whose sole focus is on, say, South America. -- Tim Parenti
Hi Tim, El lun, 3 nov 2025 a las 20:37, Tim Parenti (<tim@timtimeonline.com>) escribió:
But everyday applications generally do ultimately need to store and display some information about the past in addition to information about the present and future. As such, any algorithmic simplification of the full zone set will inevitably fail someone or something for some purpose, because how you decide what to include and what to shed will vary.
Sure this makes sense in general, but for my application (an embedded system that needs to schedule events) historical data is completely irrelevant. BR, Guillermo Rodriguez Garcia guille.rodriguez@gmail.com
Hi Paul, El lun, 3 nov 2025 a las 20:19, Paul Eggert (<eggert@cs.ucla.edu>) escribió:
On 2025-11-03 10:53, Guillermo Rodriguez Garcia wrote:
zonenow.tab has a very limited set of timezones, so for many countries, the precondition "if at least one of its timezones appear in zonenow.tab" will not be met.
Oh, good point. I was trying to come up with something simple but evidently it needs to be trickier.
Here's an idea. Make the following change to Makefile:
[...]
and then run "make now.ck". Then look at now.ckd/zdump-now.tab to decide whether two timezones have equivalent behavior from now on.
But if I am understanding correctly, this is the part of the problem that I have already solved. I mean, I am already finding pairs of timezones that have equivalent behavior from now on. What I don't know, when I find these, is which ones to keep and which ones to drop. From the example in my original email: for Spain I would keep Europe/Madrid and drop Africa/Ceuta. Another example: for Germany I would keep Europe/Berlin and drop Europe/Busingen. The question is, once I find these "equivalent from now on" timezones (which is the part I solved already), how to make that decision. BR, Guillermo Rodriguez Garcia guille.rodriguez@gmail.com
On Mon, 3 Nov 2025 at 14:45, Guillermo Rodriguez Garcia < guille.rodriguez@gmail.com> wrote:
for my application (an embedded system that needs to schedule events) historical data is completely irrelevant.
That is a valid case and it will likely work well for you, then! As it is more the exception than the rule, though, I feel it's important to occasionally remind others reading the list that, like with many things in life, there's no such thing as a one-size-fits-all solution. -- Tim Parenti
Even for scheduling systems, some historical time zone data may still be needed. Consider if you have a recurring task in a time zone that has an upcoming standard offset change or DST rule change. Before the change, you only needed to know that it was coming up. But as soon as the change has come into effect, the old rules are now the "historical data". Sure - you might* not need the old rules for scheduling the next occurrence, but your application may have other reasons to reference the old rules (reports, etc.) * I've also worked on some scheduling systems where the original first occurrence date is kept in terms of local time, and future dates are based on that original date. In this case, the old and the new rules must both be available to schedule any future occurrence. On Mon, Nov 3, 2025 at 11:51 AM Tim Parenti via tz <tz@iana.org> wrote:
On Mon, 3 Nov 2025 at 14:45, Guillermo Rodriguez Garcia < guille.rodriguez@gmail.com> wrote:
for my application (an embedded system that needs to schedule events) historical data is completely irrelevant.
That is a valid case and it will likely work well for you, then! As it is more the exception than the rule, though, I feel it's important to occasionally remind others reading the list that, like with many things in life, there's no such thing as a one-size-fits-all solution.
-- Tim Parenti
On 2025-11-03 11:23, Paul Gilmartin via tz wrote:
On 11/2/25 03:11, Guillermo Rodriguez Garcia via tz wrote:
So, the question: Any suggestions on how to filter timezones within each country to drop those that as of today are not relevant except for historical differences?
Use zonenow.tab rather than zone{,1970}.tab.
The last line of each timezone definition appears to contain the current POSIX definition. (I don't know where this is documented.)
"Version 2 format" in tzfile(5)
If those lines are identical, might zones be merged? That could be one possible approach, but would need to be checked. Another might be to compare all tzdata fields.
-- Take care. Thanks, Brian Inglis Calgary, Alberta, Canada La perfection est atteinte Perfection is achieved non pas lorsqu'il n'y a plus rien à ajouter not when there is no more to add mais lorsqu'il n'y a plus rien à retrancher but when there is no more to cut -- Antoine de Saint-Exupéry
Hi, El El lun, 3 nov 2025 a las 21:07, Brian Inglis via tz <tz@iana.org> escribió:
On 2025-11-03 11:23, Paul Gilmartin via tz wrote:
On 11/2/25 03:11, Guillermo Rodriguez Garcia via tz wrote:
So, the question: Any suggestions on how to filter timezones within each country to drop those that as of today are not relevant except for historical differences?
Use zonenow.tab rather than zone{,1970}.tab.
No. This does not meet the first of my two requirements.
The last line of each timezone definition appears to contain the current POSIX definition. (I don't know where this is documented.)
"Version 2 format" in tzfile(5)
If those lines are identical, might zones be merged? That could be one possible approach, but would need to be checked. Another might be to compare all tzdata fields.
In any case this is the part of the problem I have solved already. The missing bit is how to pick the winner when merging. Guillermo
On 2025-11-03 13:10, Guillermo Rodriguez Garcia wrote:
El lun, 3 nov 2025 a las 21:07, Brian Inglis via tz escribió:
On 2025-11-03 11:23, Paul Gilmartin via tz wrote: > On 11/2/25 03:11, Guillermo Rodriguez Garcia via tz wrote: >> So, the question: Any suggestions on how to filter timezones within >> each country to drop those that as of today are not relevant except >> for historical differences?
Use zonenow.tab rather than zone{,1970}.tab.
No. This does not meet the first of my two requirements.
> The last line of each timezone definition appears to contain the current > POSIX definition. (I don't know where this is documented.)
"Version 2 format" in tzfile(5)
> If those lines are identical, might zones be merged? That could be one possible approach, but would need to be checked. Another might be to compare all tzdata fields.
In any case this is the part of the problem I have solved already. The missing bit is how to pick the winner when merging.
Population is the criterion for preferring identifiers - see: https://data.un.org/Data.aspx?d=POP&f=tableCode:240 -- Take care. Thanks, Brian Inglis Calgary, Alberta, Canada La perfection est atteinte Perfection is achieved non pas lorsqu'il n'y a plus rien à ajouter not when there is no more to add mais lorsqu'il n'y a plus rien à retrancher but when there is no more to cut -- Antoine de Saint-Exupéry
On 2025-11-03 11:50, Guillermo Rodriguez Garcia wrote:
What I don't know, when I find these, is which ones to keep and which ones to drop.
Oh, I see. That problem is easy to solve if one of the timezones is listed in zonenow.tab; just use that timezone. But you do have an issue if none of them are in zonenow.tab. How about if you create an auxiliary table with estimated populations of each timezone. That would let you choose which one to keep among several candidates, none of which are in zonenow.tab. You'd then need to maintain that table, and deal with the problem we've already run into in TZDB where a timezone becomes #1 in population but people are used the old #1 (atop the problem I mentioned earlier when the definition of "now" changes as time passes). But as long as you're willing to do the maintenance that should be good enough (though not "perfect", as I keep saying...).
participants (8)
-
Arthur Olson -
Brian Inglis -
Guillermo Rodriguez Garcia -
Justin Grant -
Matt Johnson-Pint -
Paul Eggert -
Paul Gilmartin -
Tim Parenti