Files
timeTableFix/src/lib/date.js
timeTable2 dev 02cfdda900 refactor: extract date.js, event-factory.js, split.js; use shared date helpers in recur/organize
- 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
2026-07-13 20:01:10 +08:00

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())}`
}