Skip to main content

Show the right date and time

Frames are prepared shortly before they go on display. So that your Widget shows the right time, the clock is moved forward to the moment your Frame goes on display. new Date() and Date.now() give you that moment, with nothing else to do:

import { useTimeZone } from "~lib/use-time-zone";

export const Widget = () => {
const timeZone = useTimeZone();

return (
<h1>
{new Date().toLocaleTimeString(undefined, {
timeZone,
hour: "2-digit",
minute: "2-digit",
})}
</h1>
);
};

Always pass the Frame's time zone, from useTimeZone, when you format a time. The browser that draws your Widget isn't in the Frame's time zone, so getHours(), or formatting without a timeZone, gives the wrong hour on the Frame, even when it looks right in the preview.

A Frame prepared for midnight shows midnight, and "today" is the day your Frame goes on display. In the Widget Studio preview, it is simply the current time.

new Date(...) with a value, such as a date string to parse, works as usual.

Data you fetch​

Your Widget fetches its data when the Frame is prepared, a little before it goes on display. Most of the time that makes no difference, but an API that hands you "today's" forecast without being told the day gives you the day before for a Frame prepared just before midnight.

Ask for the day you want, or pick it out of the results using new Date():

import { useFetch } from "~lib/use-fetch";
import { useTimeZone } from "~lib/use-time-zone";

type Forecast = {
readonly days: { readonly date: string; readonly high: number }[];
};

export const Widget = () => {
const timeZone = useTimeZone();
const { data } = useFetch<Forecast>(
"https://api.example.com/forecast?days=2",
);

// The day your Frame goes on display, written like 2030-01-31 to match the API's dates.
const today = new Date().toLocaleDateString("en-CA", { timeZone });
const forecast = data.days.find((day) => day.date === today) ?? data.days[0];

return <h1>{forecast.high}°</h1>;
};

The hooks​

You never need a hook to read the time, but two are there when you want to be precise:

  • useScheduledDate gives the moment your Frame goes on display, for when you want your code to say so.
  • useRenderDate gives the real time your Frame is being prepared, for the rare API that checks a timestamp you send against its own clock, such as a signed request.