Skip to content

udiNur/tzy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tzy — terminal world clock for distributed teams

A colorful TUI world clock with an interactive 24-hour timeline, fuzzy timezone search, and in-app zone management. Built with Bubble Tea and Lip Gloss in Go.

Go Version License: MIT Built with Charm Platform: macOS | Linux

tzy main view

See at a glance who's asleep, who's at lunch, and who's about to log off — without doing the math. Designed for remote teams, distributed engineering, on-call rotations, and anyone who lives across timezones.

Keywords: world clock, timezone, time zone, TUI, terminal UI, CLI, remote work, distributed teams, cross-timezone, Bubble Tea, Lip Gloss, Go, golang, IANA, tzdata.

Why tzy?

  • Designed for the terminal — no Electron, no browser, ~5 MB single binary. Launches in milliseconds.
  • Visual at a glance — color-coded hour bands let you parse "is 9am in Tokyo a good time to ping?" in one second.
  • Searchable — fuzzy-find timezones by country (china), city (shanghai), code (jp), or IANA path.
  • No mouse needed — fully keyboard-driven, vim-style bindings.
  • Themeable — every hour band's foreground/background is a hex color in your config.

Features

  • 24-hour color-coded timeline per timezone, themed by hour bands (night / morning / midday / afternoon / early-evening / evening / late-evening).
  • Time-travel cursor←/→ to scrub by hour, Shift+←/→ for ±24h. Wall-clock "now" stays highlighted in amber regardless of where the cursor is.
  • Fuzzy search (/) — filter zones by alias; home and pinned zones always remain visible.
  • In-app add / remove / reorder / rename of zones. The add flow autocompletes against the full IANA database (~418 zones) by country, city, or path.
  • Synthetic "Local" row when your system timezone differs from your home zone, so you always know what time it is for you.
  • Pin / unpin zones to keep them visible during search.
  • Toggleable columns: IANA path, friendly name ("Pacific", "Eastern", "Israel"…), short abbreviation ("PDT", "EDT", "IDT"…).
  • Clipboard copy of the focused time.
  • Persistent state — pins, column toggles, and aliases survive restarts.

Installation

Quick install (macOS / Apple Silicon — Homebrew prefix)

Requires Go 1.23+.

git clone https://github.com/udiNur/tzy.git
cd tzy
make install

This builds ./tzy, symlinks /opt/homebrew/bin/tz → ./tzy, and seeds ~/.config/tzy/config.toml with the example config. From any shell:

tz

Because it's a symlink, every go build (or make build) in the project directory immediately updates the system-wide tz command — no re-install step needed.

Custom install prefix

make install PREFIX=/usr/local       # symlinks /usr/local/bin/tz
make install PREFIX="$HOME/.local"   # symlinks ~/.local/bin/tz

Uninstall

make uninstall    # removes the symlink; your config is left at ~/.config/tzy/

Manual build

go build -o tzy .
./tzy --config config.toml

Usage

tz                         # launches with config from --config / ./config.toml / $XDG_CONFIG_HOME/tzy/ / ~/.config/tzy/
tz --config path.toml      # override config path

Keybindings

Keys Action
/ h l Move cursor ±1 hour
Shift+← Shift+→ / H L Move cursor ±24 hours
t / 0 Jump cursor back to current hour
c / Enter Copy focused time to clipboard
/ j k Select row
K J (shift+k / shift+j) Move selected zone up / down
p Pin / unpin selected zone
e Edit alias of selected zone
a Add new zone (with country/city autocomplete)
d Delete selected zone (asks y/n)
/ Fuzzy-search by alias
n Toggle IANA path column
N (shift+n) Toggle friendly-name column
Ctrl+N Toggle short-abbreviation portion of the name column
q / Esc / Ctrl+C Quit (esc clears active filter first)

Adding a zone

Press a, then type freely — the catalog searches across country name, country code (e.g. jp), IANA city, and full path. Use ↑/↓ to highlight a suggestion, Enter to commit.

add flow with autocomplete


Configuration

tzy reads a TOML config from (in order): --config <path>, ./config.toml, $XDG_CONFIG_HOME/tzy/config.toml, ~/.config/tzy/config.toml.

Example

# Your zones. First entry is "home" (★) — by convention your primary timezone.
[[timezones]]
tz    = "Asia/Jerusalem"
alias = "Jerusalem"

[[timezones]]
tz    = "America/New_York"
alias = "New York"

[[timezones]]
tz    = "Europe/Lisbon"
alias = "Lisbon"

# Color bands. Each block covers [start_hour, end_hour); first match wins.
[[blocks]]
name = "night"
start_hour = 0
end_hour   = 8
bg = "#1E1E1E"
fg = "#A9A9A9"

[[blocks]]
name = "morning"
start_hour = 8
end_hour   = 11
bg = "#1B5E20"
fg = "#FFFFFF"

[[blocks]]
name = "midday"
start_hour = 11
end_hour   = 15
bg = "#2E7D32"
fg = "#FFFFFF"

[[blocks]]
name = "evening"
start_hour = 18
end_hour   = 22
bg = "#1565C0"
fg = "#E0E0E0"

Any change you make through the TUI (a/d/K/J/e) writes back to this file via atomic temp-file rename. Comments and original formatting are not preserved on rewrite.

Runtime state

Pin list, column-toggle preferences, and similar UI state live separately in ~/.config/tzy/state.toml (or $XDG_CONFIG_HOME/tzy/state.toml). You usually don't need to edit this by hand.


How "home" and "local" work

  • Home is positional: it's always the first entry in your [[timezones]] list, marked with ★. If you reorder, the new first entry becomes home.
  • Local is detected from $TZ and /etc/localtime. If your system zone differs from home, a synthetic L Local · <City> row is prepended automatically. It's not in your config — it disappears if you set your system zone to match home.

Development

make build      # go build -o tzy .
make run        # build + run
go vet ./...
go test ./...

Architecture notes for contributors are in CLAUDE.md.


License

MIT.

About

A colorful TUI world clock with an interactive 24-hour timeline, fuzzy timezone search, and in-app zone management. Built with Bubble Tea + Lip Gloss.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors