Timezone Clock
attn-ui/timezone-clockFreeComponent
A real-time clock component that displays time in any timezone with animated transitions and timezone offset indicators.
Install it
npx shadcn@latest add https://attnui.com/r/timezone-clock.jsonSource
1"use client";23import { useEffect, useState } from "react";4import NumberFlow from "@number-flow/react";56export function TimezoneClock({7 timezone = "Asia/Kolkata",8}: {9 timezone: Intl.DateTimeFormatOptions["timeZone"];10}) {11 const [time, setTime] = useState<{ hours: string; minutes: string }>({12 hours: "00",13 minutes: "00",14 });15 const [timezoneOffset, setTimezoneOffset] = useState<{16 diff: number;17 label: string;18 } | null>(null);1920 useEffect(() => {21 const updateTime = () => {22 const resumeTimezone = timezone;23 const now = new Date();2425 const formatter = new Intl.DateTimeFormat("en-US", {26 timeZone: resumeTimezone,27 hour: "2-digit",28 minute: "2-digit",29 hour12: false,30 });3132 const parts = formatter.formatToParts(now);33 const hours = parts.find((p) => p.type === "hour")?.value || "00";34 const minutes = parts.find((p) => p.type === "minute")?.value || "00";3536 setTime({ hours, minutes });3738 const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;3940 if (userTimezone !== resumeTimezone) {41 const getOffset = (tz: string) => {42 const date = new Date();43 const utcDate = new Date(44 date.toLocaleString("en-US", { timeZone: "UTC" }),45 );46 const tzDate = new Date(47 date.toLocaleString("en-US", { timeZone: tz }),48 );49 return (tzDate.getTime() - utcDate.getTime()) / (1000 * 60);50 };5152 const userOffset = getOffset(userTimezone);53 const resumeOffset = getOffset(resumeTimezone);54 const diffInMinutes = userOffset - resumeOffset;55 const diffInHours = Math.abs(diffInMinutes / 60);5657 const label =58 diffInMinutes > 059 ? `${diffInHours}h ahead`60 : `${diffInHours}h behind`;6162 setTimezoneOffset({ diff: diffInHours, label });63 } else {64 setTimezoneOffset(null);65 }66 };6768 updateTime();69 const interval = setInterval(updateTime, 1000 * 60); // Update every minute7071 return () => clearInterval(interval);72 }, [timezone]);7374 return (75 <div className="flex items-center gap-2 font-mono">76 <div className="flex items-center">77 <NumberFlow78 value={parseInt(time.hours)}79 format={{ minimumIntegerDigits: 2 }}80 className="tabular-nums"81 />82 <span>:</span>83 <NumberFlow84 value={parseInt(time.minutes)}85// … truncated
What it pulls in
npm packages
Files it writes
More from attn-ui
All 6 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Avatar Stackanimated-avatar-stack | attn-ui | Components | Free | 2 deps · 2 files | |
| avataravatar | attn-ui | Components | Free | 1 dep | |
| buttonbutton | attn-ui | Components | Free | no deps | |
| Nested Menu Drawernested-drawer | attn-ui | Components | Free | 1 dep · 2 files | |
| tooltiptooltip | attn-ui | Components | Free | 1 dep |
