fizz.today

I’ve been typing timezone names from memory for years. TZ=[tab] was always there.

I needed to tell someone in Italy my availability in their timezone. I’ve done this a hundred times — open a browser, search “Italy timezone IANA,” copy the string, paste it back into the terminal.

This time I typed TZ= and hit tab.

$ TZ=<tab>
 -- time zone --
Africa/      Asia/        CET          Cuba         Egypt        Factory      GMT+0        HST          Iran         Kwajalein    MST7MDT      Navajo       Poland       Singapore    UTC          Zulu
America/     Atlantic/    CST6CDT      EET          Eire         GB           GMT-0        Hongkong     Israel       Libya        Mexico/      PRC          Portugal     Turkey       Universal
Antarctica/  Australia/   Canada/      EST          Etc/         GB-Eire      GMT0         Iceland      Jamaica      MET          NZ           PST8PDT      Pacific/     ROC          UCT          W-SU
Arctic/      Brazil/      Chile/       EST5EDT      Europe/      GMT          Greenwich    Indian/      Japan        MST          NZ-CHAT      PST8PDT      ROK          US/          WET

Continents. I typed E and tabbed to winnow:

$ TZ=E<tab>
 -- time zone --
EET      EST      EST5EDT  Egypt    Eire     Etc/     Europe/

Then u[tab] — enough to complete Europe/ — and tabbed again:

$ TZ=Europe/<tab>
Amsterdam    Belfast      Busingen     Dublin       Helsinki     Kaliningrad  London       Minsk        Oslo         Riga         Simferopol   Tiraspol     Vienna       Zagreb
Andorra      Belgrade     Chisinau     Gibraltar    Istanbul     Kiev         Luxembourg   Monaco       Paris        Rome         Skopje       Ulyanovsk    Vilnius      Zaporozhye
Astrakhan    Berlin       Copenhagen   Guernsey     Jersey       Kirov        Madrid       Moscow       Podgorica    Samara       Sofia        Uzhgorod     Volgograd    Zurich
Athens       Bratislava   Dublin       Helsinki     Kaliningrad  Lisbon       Malta        Nicosia      Prague       San_Marino   Stockholm    Vaduz        Warsaw

R[tab]:

$ TZ=Europe/R<tab>
 -- time zone --
Riga  Rome

o[tab]TZ=Europe/Rome. Seven keystrokes and four tabs.

You don’t have to know every city and region in the database. You don’t have to memorize anything. It’s a self-revealing affordance — each tab unfolds the next layer. TZ=Rome[tab] gives you nothing — don’t start with a city. TZ=[tab] gives you the whole menu. You don’t even have to know that Italy is under Europe/ — presented with a list of continents, you’ll pick the right one. Then you unwrap it from there.

How I found the machinery

After it worked, I had to know where the names were coming from. Zsh completions are functions that live in $fpath, so I grepped for TZ-specific logic:

$ grep -R "TZ" /usr/share/zsh/5.9/functions/
/usr/share/zsh/5.9/functions/_time_zone:#compdef -value-,TZ,-default-

One hit. A function called _time_zone. That #compdef -value-,TZ,-default- line at the top is how zsh registers a completion function — it tells the completion system “when someone tabs after TZ=, call me.” I read the rest:

$ cat /usr/share/zsh/5.9/functions/_time_zone
#compdef -value-,TZ,-default-
local _zoneinfo_dirs=(/usr/{share,lib,share/lib}/zoneinfo(/N))
(( $#_zoneinfo_dirs )) &&
  _wanted time-zones expl 'time zone' _files -g '[A-Z]*' \
    -M 'm:{a-z}={A-Z}' -W _zoneinfo_dirs

Four lines, and every one is doing something clever. The #compdef -value-,TZ,-default- directive hooks on the value position after TZ= — not on a command name, which is how most completers work. It fires whenever any command has TZ= in its arguments. The -g '[A-Z]*' glob filters out the POSIX compatibility junk in zoneinfo (lowercase files like posixrules) so you only see real regions and cities. The -M 'm:{a-z}={A-Z}' flag means case-insensitive matching — TZ=e[tab] works just as well as TZ=E[tab]. And the real stroke: it uses _files, the filesystem completer. There is no lookup table. The IANA tz database is already a directory tree, and the completer just walks it.

I was about to write a timezone lookup function because I refused to google it one more time. Seven keystrokes and four tabs.

#zsh #cli #platformengineering