メインコンテンツまでスキップ

正しい日付と時刻を表示する

フレームの表示内容は、実際に表示される少し前に準備されます。ウィジェットが正しい時刻を表示できるよう、時計はフレームに表示される瞬間まで進めてあります。new Date()やDate.now()はその瞬間を返すので、特別なことは何もする必要がありません。

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>
);
};

時刻を書式化するときは、必ずuseTimeZoneで取得したフレームのタイムゾーンを渡してください。ウィジェットを描画するブラウザーはフレームのタイムゾーンにはないため、getHours()を使ったり、timeZoneを指定せずに書式化したりすると、プレビューでは正しく見えても、フレームでは時刻がずれてしまいます。

0時に表示するために準備されたフレームには0時が表示され、「今日」はフレームに表示される日を指します。ウィジェットスタジオのプレビューでは、単に現在の時刻になります。

日付の文字列を解析する場合など、new Date(...)に値を渡したときは、いつもどおりに動作します。

取得するデータ​

ウィジェットがデータを取得するのは、フレームの表示内容が準備されるとき、つまり表示される少し前です。ほとんどの場合は違いが出ませんが、日付を指定しなくても「今日」の天気予報を返すAPIの場合、0時の直前に準備されたフレームには前日の予報が返ってきます。

必要な日付を指定してリクエストするか、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",
);

// フレームに表示される日。APIの日付に合わせて、2030-01-31の形式で書きます。
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>;
};

フック​

時刻を読み取るのにフックは必要ありませんが、厳密に扱いたいときのために2つ用意されています。

  • useScheduledDateは、フレームに表示される瞬間を返します。そのことをコードの上でもはっきりさせたいときに使います。
  • useRenderDateは、フレームの表示内容が実際に準備されている時刻を返します。署名付きリクエストのように、送られたタイムスタンプをAPI自身の時計と照合する、まれなケースで使います。