Dates and numbers Required
Show times in the user's time zone
Show every moment in time in the user's chosen time zone, and name the zone wherever people in different zones see the same screen.
How to do it
Receive instants from the API in UTC, as dates and times requires. Store each user's IANA zone, such as Europe/Stockholm, in their profile. Default it to the browser's zone. Format with a locale and that zone, as locale formats shows. On shared screens, such as a team calendar, add the short zone name to each time.
Example
export function formatInstant(isoUtc: string, user: { locale: string; timeZone: string }): string {
return new Intl.DateTimeFormat(user.locale, {
dateStyle: 'medium',
timeStyle: 'short',
timeZone: user.timeZone,
timeZoneName: 'short',
}).format(new Date(isoUtc));
}
from datetime import datetime
from zoneinfo import ZoneInfo
from babel import Locale
from babel.dates import format_datetime
def format_instant(iso_utc: str, locale_tag: str, time_zone: str) -> str:
zone = ZoneInfo(time_zone)
moment = datetime.fromisoformat(iso_utc).astimezone(zone)
locale = Locale.parse(locale_tag, sep="-")
return format_datetime(moment, "medium", tzinfo=zone, locale=locale) + " " + moment.tzname()
How to check
Run the component tests in two far-apart zones, such as TZ=Pacific/Kiritimati and TZ=America/Los_Angeles, with the profile zone set to Europe/Stockholm. Every rendered time is the same in both runs.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/dates-and-numbers/user-time-zone.