atmo.rsvp
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 2953d729cb2b4e5a89bd7e01fa616da57e208475 55 lines 1.9 kB view raw
1import { parseAbsolute, parseDateTime } from '@internationalized/date'; 2 3/** 4 * Convert a datetime-local string (e.g. "2026-04-09T22:00") to a UTC ISO string, 5 * interpreting the wall-clock components in the given IANA timezone. 6 */ 7export function datetimeLocalToISO(dt: string, tz: string): string { 8 return parseDateTime(dt).toDate(tz).toISOString(); 9} 10 11/** 12 * Convert a UTC ISO string to a datetime-local string ("YYYY-MM-DDTHH:mm") whose 13 * components represent the wall-clock time in the given IANA timezone. 14 */ 15export function isoToDatetimeLocalInTz(iso: string, tz: string): string { 16 const zdt = parseAbsolute(iso, tz); 17 const pad = (n: number) => n.toString().padStart(2, '0'); 18 return `${zdt.year}-${pad(zdt.month)}-${pad(zdt.day)}T${pad(zdt.hour)}:${pad(zdt.minute)}`; 19} 20 21/** 22 * Format an ISO timestamp using Intl options, rendered in the event's timezone 23 * when available. Falls back to the viewer's local zone for legacy events that 24 * predate the timezone field. 25 */ 26export function formatInTz( 27 iso: string, 28 tz: string | undefined, 29 options: Intl.DateTimeFormatOptions, 30 locale: string = 'en-US' 31): string { 32 const date = new Date(iso); 33 return new Intl.DateTimeFormat(locale, { ...options, timeZone: tz || undefined }).format(date); 34} 35 36/** 37 * Returns the parts of an ISO timestamp in the given timezone (or viewer-local 38 * when tz is falsy). Useful when the caller wants numeric components like the 39 * day-of-month rendered in the event's zone. 40 */ 41export function partsInTz( 42 iso: string, 43 tz: string | undefined, 44 options: Intl.DateTimeFormatOptions, 45 locale: string = 'en-US' 46): Record<string, string> { 47 const date = new Date(iso); 48 const parts = new Intl.DateTimeFormat(locale, { 49 ...options, 50 timeZone: tz || undefined 51 }).formatToParts(date); 52 const out: Record<string, string> = {}; 53 for (const p of parts) if (p.type !== 'literal') out[p.type] = p.value; 54 return out; 55}