import { moment } from "obsidian"; import type { M } from "./types"; /** * Parse a date-ish input (frontmatter Date object, "YYYY-MM-DD" string, or any * moment-parseable string) into a moment. Returns null if unparseable. */ export function parseMoment(input: unknown): M | null { if (input == null || input === "") return null; if (input instanceof Date) { if (Number.isNaN(input.getTime())) return null; const isUtcMidnight = input.getUTCHours() === 0 && input.getUTCMinutes() === 0 && input.getUTCSeconds() === 0 && input.getUTCMilliseconds() === 0; if (isUtcMidnight) { return moment({ year: input.getUTCFullYear(), month: input.getUTCMonth(), day: input.getUTCDate(), }).startOf("day"); } return moment(input); } const s = String(input).trim(); const dateOnly = moment(s, "YYYY-MM-DD", true); if (dateOnly.isValid()) return dateOnly.startOf("day"); const any = moment(s); return any.isValid() ? any : null; } /** Break the span between two moments into years/months/days/hours/minutes. */ export function formatSpan( from: M, to: M, verbose: boolean ): { text: string; isNegative: boolean } { let a = from.clone(); let b = to.clone(); const isNegative = b.isBefore(a); if (isNegative) [a, b] = [b, a]; const years = b.diff(a, "years"); a.add(years, "years"); const months = b.diff(a, "months"); a.add(months, "months"); const days = b.diff(a, "days"); a.add(days, "days"); const hours = b.diff(a, "hours"); a.add(hours, "hours"); const minutes = b.diff(a, "minutes"); if (verbose) { const parts: string[] = []; if (years) parts.push(`${years} year${years === 1 ? "" : "s"}`); if (months) parts.push(`${months} month${months === 1 ? "" : "s"}`); if (days) parts.push(`${days} day${days === 1 ? "" : "s"}`); if (hours && parts.length < 3) parts.push(`${hours} hour${hours === 1 ? "" : "s"}`); if (minutes && parts.length < 3) parts.push(`${minutes} minute${minutes === 1 ? "" : "s"}`); return { text: parts.join(", ") || "0 minutes", isNegative }; } else { const parts: string[] = []; if (years) parts.push(`${years}y`); if (months) parts.push(`${months}mo`); if (days) parts.push(`${days}d`); if (hours && parts.length < 3) parts.push(`${hours}h`); if (minutes && parts.length < 3) parts.push(`${minutes}m`); return { text: parts.join(" ") || "0m", isNegative }; } }