/** * THE STAMPS ON THE PATIENT'S OWN HISTORY, at the granularity a person thinks in. * * `toLocaleString()` with no options printed "9/4/2026, 8:54:12 PM". Two things are wrong with that on * this screen, and neither is taste: * * SECONDS ARE THE SYSTEM'S GRANULARITY, NOT A PERSON'S. Nobody has ever needed to know that two reads * were three seconds apart, and printing it invites the reader to treat a burst of API calls as a * sequence of deliberate acts. On a screen built so a patient can notice something wrong, that is the * expensive direction to be wrong in. * * A NUMERIC DATE IS AMBIGUOUS TO HALF THE WORLD. "9/4/2026" is September 4th here and April 9th to a * reader who learned the other order, and this is a record somebody may be checking against their own * memory of a specific day. The month name cannot be misread. */ const DAY: Intl.DateTimeFormatOptions = { month: 'short', day: 'numeric', year: 'numeric' }; const CLOCK: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: '2-digit' }; export const formatHistoryMoment = (iso: string | undefined): string => { if (!iso) return 'an unknown time'; const at = new Date(iso); if (Number.isNaN(at.getTime())) return 'an unknown time'; return `${at.toLocaleDateString(undefined, DAY)}, ${at.toLocaleTimeString(undefined, CLOCK)}`; }; /** Just the clock part, for a range whose date is already established by the row above it. */ export const formatHistoryClock = (iso: string | undefined): string => { if (!iso) return 'an unknown time'; const at = new Date(iso); if (Number.isNaN(at.getTime())) return 'an unknown time'; return at.toLocaleTimeString(undefined, CLOCK); }; /** * "2:11-2:14 PM", with the meridiem said ONCE when both ends share it. * * "2:11 PM - 2:14 PM" reads as two separate times a reader has to compare; said once it reads as a * span, which is the thing being described. Across noon or midnight both are kept, because there the * meridiem is the whole information. * * FALLS BACK TO A SINGLE STAMP when the two ends are the same minute. A range from a time to itself * looks like a rendering fault, and it is the ordinary case here - most things are read once. */ export const formatHistoryClockRange = (from: string | undefined, to: string | undefined): string => { const start = formatHistoryClock(from); const end = formatHistoryClock(to); if (!to || start === end) return start; if (start === 'an unknown time' || end === 'an unknown time') return start; // Split on the LAST space: the meridiem is the trailing token in every locale that has one, and a // locale with none simply finds nothing to share and keeps both halves whole. const startMeridiem = start.slice(start.lastIndexOf(' ') + 1); const endMeridiem = end.slice(end.lastIndexOf(' ') + 1); if (startMeridiem && startMeridiem === endMeridiem && start.includes(' ')) { return `${start.slice(0, start.lastIndexOf(' '))}–${end}`; } return `${start}–${end}`; };