Skip to content

nembal/Timezoner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TimeZoner

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.

TimeZoner docked to menu bar Docked to the menu bar

TimeZoner floating with world map Floating, with the timezone map open

Install

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.

Cleanest local install

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 --open

This builds TimeZoner, signs it locally, and installs it to:

~/Applications/TimeZoner.app

Use ./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 --install

Cleanest Homebrew install

Use 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.app

timezoner-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-app

Manual DMG install

The 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.

Raycast local install

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 dev

Open 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.

How it works

Just start typing. The chat field is focused when the app opens. Type a time and a city, hit Enter.

Set a time in any zone

3pm SF              → all cards update
11:30am bangkok     → all cards update
15:00 BKK           → 24-hour format works too
noon NYC            → special words work

Compare across zones

1130am BKK in SF    → sets Bangkok time, highlights both cards
3pm london in tokyo → see what London afternoon is in Tokyo

Quick bare time (applies to your active zone)

11:30               → updates whichever card was last edited
3pm                 → first card is your "home" zone by default

Add and remove zones

+Tokyo              → adds a Tokyo card
add Hong Kong       → adds Hong Kong
-SF                 → removes SF
remove Europe       → removes Europe

Timezone map

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.

Edit cards directly

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.

Drag to reorder

Hover a card and a small pill appears at the top. Grab it and drag left or right to rearrange your zones.

Docks to the menu bar

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.

Stays on top

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).

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

Works offline

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.

Forgiving input

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

Raycast Raycast Extension

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.

Local Raycast install

git clone https://github.com/nembal/Timezoner.git
cd Timezoner/raycast
npm install
npm run dev

Open Raycast, type tz to open TimeZoner, then enter 3pm in SF.

You can also import it manually: Raycast → Settings → Extensions → + → Import Extension → select the raycast/ 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.

Build from source

git clone https://github.com/nembal/Timezoner.git
cd Timezoner
./build.sh
open app/TimeZoner.app

Create 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 build

Deep-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.

Tech stack

  • SwiftUI + AppKit — borderless floating NSPanel
  • Swift Package Manager — no Xcode project needed
  • macOS 14+ — Observation framework (@Observable)
  • Zero dependencies — no network, no external packages

License

MIT — see LICENSE.

About

Lightweight macOS floating-panel app for instant timezone conversion. Natural language input, live-updating cards, 376 timezone aliases. SwiftUI + AppKit.

Topics

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors