isecond formatting latency across modern engines
- Predictable UI stability when combined with tabular numeric rendering
- Directly compatible with browser extension environments (e.g., Firefox Add-ons)
Core Solution
The Core Function
function getTimeInZone(timezone) {
return new Intl.DateTimeFormat("en-US", {
timeZone: timezone,
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
}).format(new Date());
}
// Usage
getTimeInZone("America/New_York"); // "14:32:07"
getTimeInZone("Europe/London"); // "19:32:07"
getTimeInZone("Asia/Tokyo"); // "04:32:07"
Add Date and City
function getClockData(timezone, cityName) {
const now = new Date();
const formatter = new Intl.DateTimeFormat("en-US", {
timeZone: timezone,
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
weekday: "short",
month: "short",
day: "numeric",
});
const parts = formatter.formatToParts(now);
const get = (type) => parts.find(p => p.type === type)?.value || "";
return {
city: cityName,
time: `${get("hour")}:${get("minute")}:${get("second")}`,
date: `${get("weekday")}, ${get("month")} ${get("day")}`,
};
}
Display Multiple Clocks
const CLOCKS = [
{ timezone: "America/New_York", city: "New York" },
{ timezone: "Europe/London", city: "London" },
{ timezone: "Europe/Paris", city: "Paris" },
{ timezone: "Asia/Tokyo", city: "Tokyo" },
{ timezone: "Australia/Sydney", city: "Sydney" },
];
function renderClocks() {
const container = document.getElementById("clocks");
container.innerHTML = CLOCKS.map(({ timezone, city }) => {
const { time, date } = getClockData(timezone, city);
return `
<div class="clock-card">
<div class="city">${city}</div>
<div class="time">${time}</div>
<div class="date">${date}</div>
</div>
`;
}).join("");
}
// Update every second
renderClocks();
setInterval(renderClocks, 1000);
The HTML
<div id="clocks" class="clocks-grid"></div>
<style>
.clocks-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 16px;
}
.clock-card {
background: var(--bg-secondary);
border-radius: 12px;
padding: 16px;
text-align: center;
}
.time {
font-size: 1.5rem;
font-weight: 600;
font-variant-numeric: tabular-nums;
letter-spacing: 0.05em;
}
.city { color: var(--text-secondary); font-size: 0.85rem; }
.date { color: var(--text-secondary); font-size: 0.75rem; margin-top: 4px; }
</style>
Pitfall Guide
- Proportional Font Jitter: Failing to apply
font-variant-numeric: tabular-nums causes digits with varying advance widths (e.g., 1 vs 8) to shift horizontally on every tick, creating a distracting visual jitter. Always enforce tabular rendering for time displays.
- Hardcoded UTC Offsets: Calculating time by adding/subtracting fixed hours ignores DST rules and historical timezone policy changes. Always use IANA timezone identifiers (e.g.,
America/New_York) instead of static offsets like UTC-5.
- Unoptimized DOM Re-rendering: Replacing
innerHTML on every setInterval tick forces full DOM reconstruction and layout recalculation. In production, target specific text nodes or leverage requestAnimationFrame with delta tracking to minimize repaint costs.
- Background Tab Resource Drain: Running
setInterval at 1000ms continues executing even when the tab is hidden, wasting CPU cycles and battery. Implement the Page Visibility API to pause updates when document.hidden is true.
- Missing Timezone Validation:
Intl.DateTimeFormat throws a RangeError for invalid or unsupported timezone strings. Always validate inputs against Intl.supportedValuesOf('timeZone') or wrap formatting calls in try...catch blocks to prevent runtime crashes.
Deliverables
- Blueprint: Vanilla JS World Clock Architecture Guide covering
Intl.DateTimeFormat API usage, IANA timezone validation strategies, DOM update optimization patterns, and responsive CSS Grid layout implementation for dashboard widgets.
- Checklist:
- Configuration Templates: JSON array schema for
CLOCKS data structure, CSS variable definitions for dark/light mode theming, and HTML skeleton markup for seamless integration into existing dashboard or extension environments. Full source repository available on GitHub.