<div id="app"></div>
main {
  --alpha: #0d0d0d;
  --beta: #2d2d2d;
  --gamma: #3d3d3d;
  --delta: #fafafa;
  --sigma: #fa0000;
  font-family: sans-serif;
  min-height: 100dvh;
  display: grid;
  place-items: center;
  background: var(--alpha);
  color: var(--delta);
}

.clock {
  position: relative;
  width: min(95vmax, 400px);
  aspect-ratio: 1;
  
  background: var(--gamma);
  border-radius: 50%;
  border: 20px solid var(--beta);
  rotate: -90deg;
  
  .hand {
    position: absolute;
    top: 50%;
    left: 50%;
    
    translate: 0% -50%;
    transform-origin: left;
    box-shadow: 2px 2px 5px var(--beta);
    
    &.hour {
      width: 30%;
      height: 6px;
      background: var(--delta);
    }
    
    &.min {
      width: 40%;
      height: 4px;
      background: var(--delta);
    }
    
     &.sec {
      width: 40%;
      height: 2px;
      background: var(--sigma);
    }
  }
}
View Compiled
/*
 * https://frontendeval.com/questions/analog-clock
 *
 * Create an analog clock with hour, minute, and second hands. Each of the hands should be accurate to the browser's local timezone and update once per second.
 */

const Clock = ({ tz = "Asia/Kolkata" }) => {
  const getTime = (timeZone) => {
    const t = new Intl.DateTimeFormat(
      {},
      {
        timeZone,
        hour: "numeric",
        minute: "numeric",
        second: "numeric",
        hourCycle: "h11"
      }
    ).formatToParts();

    const obj = t.reduce((acc, curr) => {
      return { ...acc, [curr.type]: +curr.value };
    }, {});

    const { hour, minute: min, second: sec, ...rest } = obj;

    return { hour, min, sec };
  };

  const getKeyframes = (value) => {
    const start = value * 30;
    const end = start + 360;

    return [
      { transform: `rotate(${start}deg)` },
      { transform: `rotate(${end}deg)` }
    ];
  };

  const hourRef = React.useRef(null);
  const minRef = React.useRef(null);
  const secRef = React.useRef(null);

  React.useEffect(() => {
    if (hourRef.current && minRef.current && secRef.current) {
      const time = getTime(tz);

      const animOptions = {
        iterations: Infinity,
        easing: "steps(60, end)"
      };

      hourRef.current.animate(getKeyframes(time.hour), {
        ...animOptions,
        duration: 3600000 * 60
      });
      
      minRef.current.animate(getKeyframes(time.min), {
        ...animOptions,
        duration: 3600000
      });
      secRef.current.animate(getKeyframes(time.sec), {
        ...animOptions,
        duration: 60000
      });
    }
  }, [hourRef, minRef, secRef]);

  return (
    <aside className="clock">
      <div className="hand hour" ref={hourRef}></div>
      <div className="hand min" ref={minRef}></div>
      <div className="hand sec" ref={secRef}></div>
    </aside>
  );
};

const App = () => {
  const TIME_ZONES = ["Asia/Kolkata", "Australia/Sydney", "America/New_York"];

  return (
    <main>
      {TIME_ZONES.map((tz) => (
        <div key={`clock-${tz}`}>
          <h2>{tz}</h2>
          <Clock tz={tz} />
        </div>
      ))}
    </main>
  );
};

ReactDOM.render(<App />, document.getElementById("app"));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js