Multi-Timezone Digital Clock — Free HTML CSS JS Snippet
Multi-Timezone Digital Clock · Dashboards · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
Multi-Timezone Digital Clock — Live City Clocks Using Intl.DateTimeFormat

Showing the correct current time for several cities at once is a common dashboard need — for distributed teams, trading desks, or travel tools — and it's easy to get wrong by hand-rolling UTC offset math, which breaks around daylight saving time transitions. This snippet instead lets the browser's built-in Intl.DateTimeFormat API do all timezone conversion.
One shared JS Date, formatted per timezone
Only a single new Date() is created per tick, representing the current moment in UTC internally. Each city then gets its own pre-built Intl.DateTimeFormat instance constructed with an explicit timeZone option (e.g. 'America/New_York', 'Asia/Tokyo') — calling .format(now) on that formatter converts the same underlying instant into that timezone's local wall-clock time correctly, including automatically handling daylight saving time, without any manual offset arithmetic anywhere in the code.
Separate formatters for time, date, and the day/night check
Three formatters are built per city up front: one for the visible time string, one for the visible date string, and a third, minimal hour: 'numeric', hour12: false formatter used only to extract that city's current local hour as a number for the day/night logic — reusing Intl.DateTimeFormat even for that internal calculation rather than parsing the display string or computing an offset by hand.
A day/night icon driven by the extracted local hour
isNightHour() treats any local hour before 6 or from 18 onward as night. Because the hour figure comes from a real timezone-aware formatter rather than the viewer's own local time, a city on the other side of the world correctly shows a moon icon and a darker card background even while the visiting browser's own clock says midday.
A single interval keeps every card in sync
One setInterval(update, 1000) re-renders every card each second from one fresh Date, so all cities' clocks always reflect literally the same instant, just displayed through a different timezone-aware formatter.
Build with AI
Build, Understand, Optimize, and Extend It With AI
Hand this snippet's HTML, CSS, and JavaScript to an AI coding assistant like Claude and ask it to adapt "Multi-Timezone Digital Clock" to your project — restyle it to match your design system, wire it up to real data instead of the static example, or port it to the framework you're building in.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a dashboards component called "Multi-Timezone Digital Clock" using plain HTML, CSS, and vanilla JavaScript — no framework, no build step.
Requirements:
- Match the structure and behavior of the "Multi-Timezone Digital Clock" snippet from the UI Snippets Library.
- Keep the markup semantic and the styling self-contained (no external dependencies beyond what the original snippet uses).
- Keep the JavaScript vanilla, with no framework runtime required.
- Make it easy to restyle via CSS custom properties or class overrides so it can be dropped into a real project.Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.
Source Code
<div class="mtz-wrap" id="mtzWrap"></div>* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, -apple-system, sans-serif; background: #f8fafc; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.mtz-wrap { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; max-width: 780px; }
.mtz-card { width: 168px; background: #fff; border: 1px solid #e2e8f0; border-radius: 16px; padding: 18px 16px; box-shadow: 0 12px 30px rgba(30,41,59,0.06); }
.mtz-card.mtz-night { background: #1e293b; border-color: #334155; }
.mtz-city-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.mtz-city { font-size: 12.5px; font-weight: 800; color: #1e293b; }
.mtz-night .mtz-city { color: #f1f5f9; }
.mtz-icon { width: 16px; height: 16px; flex-shrink: 0; color: #f59e0b; }
.mtz-night .mtz-icon { color: #93c5fd; }
.mtz-time { font-size: 24px; font-weight: 800; color: #1e293b; font-variant-numeric: tabular-nums; letter-spacing: -0.5px; margin-bottom: 4px; }
.mtz-night .mtz-time { color: #fff; }
.mtz-date { font-size: 11px; color: #94a3b8; font-weight: 600; }
.mtz-night .mtz-date { color: #94a3b8; }const CITIES = [
{ name: 'New York', tz: 'America/New_York' },
{ name: 'London', tz: 'Europe/London' },
{ name: 'Tokyo', tz: 'Asia/Tokyo' },
{ name: 'Sydney', tz: 'Australia/Sydney' },
];
const ICON_SUN = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>';
const ICON_MOON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>';
const wrap = document.getElementById('mtzWrap');
const timeFormatters = {};
const dateFormatters = {};
const hourFormatters = {};
CITIES.forEach((city) => {
timeFormatters[city.tz] = new Intl.DateTimeFormat('en-US', {
timeZone: city.tz, hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: true,
});
dateFormatters[city.tz] = new Intl.DateTimeFormat('en-US', {
timeZone: city.tz, weekday: 'short', month: 'short', day: 'numeric',
});
hourFormatters[city.tz] = new Intl.DateTimeFormat('en-US', {
timeZone: city.tz, hour: 'numeric', hour12: false,
});
});
function buildCards() {
wrap.innerHTML = CITIES.map((city, i) => `
<div class="mtz-card" id="mtzCard${i}">
<div class="mtz-city-row">
<span class="mtz-city">${city.name}</span>
<span class="mtz-icon" id="mtzIcon${i}"></span>
</div>
<div class="mtz-time" id="mtzTime${i}">--:--:--</div>
<div class="mtz-date" id="mtzDate${i}">--</div>
</div>`).join('');
}
function isNightHour(hour24) {
return hour24 < 6 || hour24 >= 18;
}
function update() {
const now = new Date();
CITIES.forEach((city, i) => {
const timeStr = timeFormatters[city.tz].format(now);
const dateStr = dateFormatters[city.tz].format(now);
const hour24 = parseInt(hourFormatters[city.tz].format(now), 10);
const night = isNightHour(hour24 === 24 ? 0 : hour24);
document.getElementById('mtzTime' + i).textContent = timeStr;
document.getElementById('mtzDate' + i).textContent = dateStr;
document.getElementById('mtzIcon' + i).innerHTML = night ? ICON_MOON : ICON_SUN;
document.getElementById('mtzCard' + i).classList.toggle('mtz-night', night);
});
}
buildCards();
update();
setInterval(update, 1000);Step by step
How to Use
- 1Load the snippetClick "Multi-Timezone Digital Clock" in the sidebar to load its HTML, CSS, and JS into the editor panels. The preview updates instantly.
- 2Edit the codeModify any panel — HTML, CSS, or JS. The preview refreshes as you type. Use Reset in each panel header to restore the original.
- 3Preview on devicesClick the Mobile (375px), Tablet (768px), or Desktop buttons in the preview header to check responsiveness.
- 4Export in your formatClick "HTML" to download a standalone file, "JSX" for a React component, "Tailwind" for a React + Tailwind CSS component, "Tailwind HTML" for a standalone HTML file with Tailwind CDN, "Vue" for a Vue 3 SFC with <template>/<script setup>/<style scoped>, or "Angular" for a standalone Angular .component.ts file. "Copy all" copies the full code to clipboard.
- 5Save your versionClick "Save as", type a name, and press Enter. Your snippet saves to IndexedDB and appears in the Saved tab.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Manual offset math breaks around daylight saving time transitions, since offsets change twice a year in many regions and vary by exact date. Intl.DateTimeFormat, given an explicit timeZone like 'America/New_York', uses the browser's built-in timezone database to always compute the correct local time automatically.
A dedicated Intl.DateTimeFormat instance per city (configured with hour: 'numeric', hour12: false) extracts that city's current local hour as a number. Any hour before 6 or from 18 onward is treated as night, independent of what time it is for the person viewing the page.
Yes — because all conversion goes through Intl.DateTimeFormat with a named IANA timezone rather than a fixed numeric offset, daylight saving transitions in any of the listed cities are handled automatically by the browser's timezone database.
Yes — add an entry to the CITIES array with a display name and a valid IANA timezone string (e.g. 'Asia/Kolkata'), and buildCards()/update() will automatically render and keep a new card in sync for it.




