/** * The calendar day the beekeeper sees on their phone, as "YYYY-MM-DD". * * Not `toISOString().slice(0, 10)`: that is the UTC day, which in Germany is * still yesterday until 01:00 (winter) or 02:00 (summer) - a form opened * shortly after midnight would prefill the wrong date. */ export function toLocalIsoDate(date: Date): string { const year = String(date.getFullYear()).padStart(4, "0"); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); return `${year}-${month}-${day}`; } /** Today's local calendar day, e.g. the default date of a new record. */ export function todayLocalIsoDate(): string { return toLocalIsoDate(new Date()); } const CALENDAR_DAY = /^\d{4}-\d{2}-\d{2}$/; /** * A day picked in a date field ("YYYY-MM-DD") as the API stores calendar * days: midnight UTC of exactly that day, whatever the phone's time zone. * Throws on anything that is not a real calendar day rather than sending a * shifted or invalid date. */ export function toApiDate(calendarDay: string): string { if (!CALENDAR_DAY.test(calendarDay)) { throw new RangeError(`Kein Kalendertag: "${calendarDay}"`); } const iso = new Date(`${calendarDay}T00:00:00.000Z`).toISOString(); if (iso.slice(0, 10) !== calendarDay) { throw new RangeError(`Kein Kalendertag: "${calendarDay}"`); } return iso; } const CALENDAR_DAY_LENGTH = 10; /** The "YYYY-MM-DD" part of an ISO timestamp as written, without any time zone shift. */ export function toCalendarDay(isoTimestamp: string): string { return isoTimestamp.slice(0, CALENDAR_DAY_LENGTH); }