I work across Bangkok, San Francisco, New York, and London. Every day I need to coordinate meetings across these timezones. Going to Google and typing "what time is 3pm SF in Bangkok" is slow — the results page loads, I click through, sometimes the AI answer helps but it takes seconds to think. I just want to type and see the answer instantly.
TimeZoner is a tiny macOS app that floats over everything. Type a time, see it in all your zones. That's it.
Floating, with the timezone map open
Requires macOS 14+ (Sonoma).
TimeZoner does not require a paid Apple Developer account to install locally. The clean install paths build the app from source on your Mac and ad-hoc sign it there.
Use this if you want the app in ~/Applications and do not care about Homebrew.
git clone https://github.com/nembal/Timezoner.git
cd Timezoner
./install.sh --openThis builds TimeZoner, signs it locally, and installs it to:
~/Applications/TimeZoner.appUse ./install.sh --applications for /Applications, or ./install.sh --destination /path/to/Applications for another folder.
If your Mac does not have Apple's command line tools yet, install them first:
xcode-select --installUse this if you want Homebrew to manage the build and updates.
brew tap nembal/timezoner https://github.com/nembal/Timezoner
brew trust --formula nembal/timezoner/timezoner
brew install timezoner
timezoner-install-app
open ~/Applications/TimeZoner.apptimezoner-install-app copies the built app bundle to ~/Applications/TimeZoner.app, so it is available from Finder, Spotlight, and Launchpad. The timezoner command also opens the Homebrew Cellar app bundle directly.
Homebrew may require the brew trust step for third-party taps before it loads the formula. To build the latest main instead of the tagged release:
brew install --HEAD nembal/timezoner/timezoner
timezoner-install-appThe DMG is a fallback for people who prefer dragging the app into Applications:
Download the latest release DMG
Open the DMG, drag TimeZoner to Applications, then right-click and choose Open on first launch if macOS asks you to confirm trust. The app is ad-hoc signed but not Apple-notarized.
Until the Raycast Store PR is merged, run the extension locally:
git clone https://github.com/nembal/Timezoner.git
cd Timezoner/raycast
npm install
npm run devOpen Raycast and type tz to launch TimeZoner. The Raycast extension works on its own; installing the native app is only needed for the Open in TimeZoner deep link.
Just start typing. The chat field is focused when the app opens. Type a time and a city, hit Enter.
3pm SF → all cards update
11:30am bangkok → all cards update
15:00 BKK → 24-hour format works too
noon NYC → special words work
1130am BKK in SF → sets Bangkok time, highlights both cards
3pm london in tokyo → see what London afternoon is in Tokyo
11:30 → updates whichever card was last edited
3pm → first card is your "home" zone by default
+Tokyo → adds a Tokyo card
add Hong Kong → adds Hong Kong
-SF → removes SF
remove Europe → removes Europe
There's a world map below the cards. Your zones show up as highlighted bands with city dots. Hover any region to see the GMT offset, click to add it as a new card. The boundaries follow real timezone lines (not straight vertical stripes), so half-hour zones like India and Nepal show up correctly. Collapse it if you don't need it.
Click any time on a card and start typing. All other cards update live as you type. Type 12 and it becomes 12:00. Type 3pm and it becomes 15:00. Hit Enter or click away to finish.
Hover a card and a small pill appears at the top. Grab it and drag left or right to rearrange your zones.
The app starts right below your menu bar with a clean flat top. Drag it down to use it as a floating widget anywhere on screen. It remembers where you put it between launches.
TimeZoner floats over all windows. Click the clock icon in your menu bar to show/hide it. Escape to dismiss. Global hotkey ⌘⌥T toggles the panel from any app (rebindable in Settings).
Click the ⚙ in the panel (or press ⌘,) to open Settings:
- Appearance — System / Light / Dark override
- Global hotkey — click the recorder and press a new combo; Esc cancels, Clear unbinds
- Launch at login — opens automatically when you sign in
- Input formats — quick reference for the chat parser
376 built-in timezone aliases — cities, abbreviations (SF, NYC, HK, BKK), airport codes (SFO, JFK, LHR), country names. No network, no API keys, no accounts.
The parser handles messy typing. All of these work:
| Input | What it does |
|---|---|
11:30am SF |
Standard format |
1130 am sf |
No colon, lowercase |
1130 a BKK |
Just "a" for AM |
3 p sf |
Just "p" for PM |
11:30 a.m. NYC |
Dotted AM/PM |
15:00 BKK |
24-hour |
noon NYC |
Special words |
midnight CET |
Midnight |
1130am BKK in SF |
Cross-zone query |
+Tokyo |
Add zone |
-SF |
Remove zone |
12 |
Bare time → active zone |
If you use Raycast, TimeZoner works there too. The extension is implemented in this repo and installs from source while the public Store submission is in review. Open TimeZoner with tz, then type 3pm in SF to see that time across every saved zone.
| Command | Keyword | What it does |
|---|---|---|
| TimeZoner | tz |
Shows current time across saved zones, converts typed times, and manages zones |
Uses the same 376 timezone aliases as the macOS app.
The Raycast command supports 3pm in SF, 3pm SF, Tokyo, +Tokyo, add Hong Kong, -SF, and remove NYC. Saved zones appear as timezone cards in a row, with the static boundary map underneath. Select any zone card and press Enter to switch the search bar into edit mode for that card; type 4:30 PM, 16:30, 15, 430pm, noon, or midnight, and every other zone recalculates live from that selected timezone. While editing, selecting another card retargets the search bar to that card in one click. The map is rendered from bundled timezone boundary data, with visible zones, matching UTC-offset regions, exact dots for common city zones, and deterministic offset markers for less common zones. You can also manage zones from the action panel: ⌘N opens Add Zone, and ⌘E edits the selected saved zone. Raycast stores its zone list in Raycast LocalStorage. It does not sync that list with the macOS app. Press ⌘O from Raycast to open TimeZoner.app through the timezoner:// URL scheme when the app is installed.
git clone https://github.com/nembal/Timezoner.git
cd Timezoner/raycast
npm install
npm run devOpen Raycast, type tz to open TimeZoner, then enter 3pm in SF.
You can also import it manually: Raycast → Settings → Extensions →
+→ Import Extension → select theraycast/directory.
Raycast Store submission is tracked at raycast/extensions#29168. The extension code, metadata screenshots, and current CI fixes are in the PR branch; public Store install depends on Raycast review and merge.
git clone https://github.com/nembal/Timezoner.git
cd Timezoner
./build.sh
open app/TimeZoner.appCreate a Manual DMG: ./scripts/create-dmg.sh 0.2.0
Run checks:
scripts/test-install.sh
cd app && swift run TimeZonerTests
cd ../raycast && npm test && npm run lint && npm run buildDeep-link smoke test:
open "timezoner://open"
open "timezoner://set?hour=15&minute=30&zone=America%2FLos_Angeles&label=SF"Release readiness is tracked in docs/RELEASE_READINESS.md.
- SwiftUI + AppKit — borderless floating NSPanel
- Swift Package Manager — no Xcode project needed
- macOS 14+ — Observation framework (
@Observable) - Zero dependencies — no network, no external packages
MIT — see LICENSE.
