t3-code-android-nightly/.repos/alchemy-effect/examples/cloudflare-website-vinext/app/components/LocalTime.tsx
Julius Marminge 6f9cea00ae
chore(refs): sync Effect and Alchemy references to 4.0.1 and beta.80 (#16170)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:22:30 -07:00

55 lines
1.3 KiB
TypeScript

import { headers } from "next/headers";
import { visitorTimezoneHeader } from "../../src/VisitorTimezone.ts";
function formatTime(
value: string | number,
locale: string,
timeZone: string,
): { iso: string; label: string } {
const date = new Date(value);
if (Number.isNaN(date.getTime())) {
return { iso: "", label: "" };
}
return {
iso: date.toISOString(),
label: date.toLocaleString(locale, {
dateStyle: "medium",
timeStyle: "medium",
timeZone,
}),
};
}
async function visitorFormat(): Promise<{ locale: string; timeZone: string }> {
const h = await headers();
const locale = h.get("accept-language")?.split(",")[0]?.split(";")[0]?.trim();
return {
locale: locale || "en-US",
timeZone: h.get(visitorTimezoneHeader()) ?? "UTC",
};
}
/**
* Server timestamp. Visitor locale + Cloudflare timezone, unless `cached`
* (UTC) for prerendered routes that must not read request headers.
*/
export async function LocalTime({
value,
cached = false,
testId,
}: {
value: string | number;
cached?: boolean;
testId?: string;
}) {
const { locale, timeZone } = cached
? { locale: "en-US", timeZone: "UTC" }
: await visitorFormat();
const { iso, label } = formatTime(value, locale, timeZone);
return (
<time data-testid={testId} dateTime={iso} title={iso}>
{label}
</time>
);
}