- date.js: single source of truth for ISO date formatting/arithmetic (toISODate, parseISODate, addDays, daysBetween, todayISO, nowCompactTimestamp) - event-factory.js: createEvent/cloneEvent (structuredClone with JSON fallback) - split.js: splitRecurringEvent pure function using intervalDays from recur.js - recur.js: replaced local toISO() and inline Date math with date.js helpers - organize.js: replaced inline date formatting and gap math with date.js helpers, extracted buildGrid() helper and byDate comparator
60 lines
1.8 KiB
JavaScript
60 lines
1.8 KiB
JavaScript
/**
|
|
* Centralized date-string utilities.
|
|
*
|
|
* All date values in the app use the 'YYYY-MM-DD' (wall-clock) format.
|
|
* These helpers are the single source of truth for formatting and
|
|
* arithmetic on that format, replacing ad-hoc inline code that was
|
|
* duplicated across organize.js, recur.js, useCalendar.js, and ical-io.js.
|
|
*/
|
|
|
|
/** Pad a number to 2 digits with leading zero. */
|
|
export function pad2(n) {
|
|
return String(n).padStart(2, '0')
|
|
}
|
|
|
|
/** Convert a JS Date to 'YYYY-MM-DD' (local wall-clock). */
|
|
export function toISODate(date) {
|
|
return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())}`
|
|
}
|
|
|
|
/** Parse 'YYYY-MM-DD' into { year, month, day } (month is 1-based). */
|
|
export function parseISODate(s) {
|
|
const [y, m, d] = s.split('-').map(Number)
|
|
return { year: y, month: m, day: d }
|
|
}
|
|
|
|
/** Build a local JS Date at midnight from 'YYYY-MM-DD'. */
|
|
export function toDate(isoDate) {
|
|
return new Date(isoDate + 'T00:00:00')
|
|
}
|
|
|
|
/** Add `days` days to an ISO date string, return new ISO string. */
|
|
export function addDays(isoDate, days) {
|
|
const d = toDate(isoDate)
|
|
d.setDate(d.getDate() + days)
|
|
return toISODate(d)
|
|
}
|
|
|
|
/** Whole-day difference between two ISO date strings (b - a). */
|
|
export function daysBetween(isoA, isoB) {
|
|
return Math.round((toDate(isoB) - toDate(isoA)) / (24 * 3600 * 1000))
|
|
}
|
|
|
|
/** Today's date as 'YYYY-MM-DD' (local). */
|
|
export function todayISO() {
|
|
return toISODate(new Date())
|
|
}
|
|
|
|
/**
|
|
* Current UTC timestamp in compact RFC 5545 form (e.g. '20260711T085008Z').
|
|
* Used for DTSTAMP on new events.
|
|
*/
|
|
export function nowCompactTimestamp() {
|
|
return new Date().toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z'
|
|
}
|
|
|
|
/** Format a JS Date's time as 'HH:MM'. */
|
|
export function toHHMM(date) {
|
|
return `${pad2(date.getHours())}:${pad2(date.getMinutes())}`
|
|
}
|