{"version":3,"file":"day.cjs","names":["TIME_DAY_MS"],"sources":["../../../src/common/data/day.ts"],"sourcesContent":["import { TIME_DAY_MS } from \"../time\"\n\n// Functionality variant\nlet testModeDay: number | undefined\n\n/**\n * Enable test mode for date functions by forcing \"today\" to a fixed day value.\n *\n * Use a numeric DayValue like 20000101 (YYYYMMDD). This is intended for tests\n * to make date-based logic deterministic. Call with no args to reset.\n *\n * @param ts - day to use as \"today\" in YYYYMMDD format (default: 20000101)\n */\nexport function setDayTest(ts = 20000101) {\n  testModeDay = ts\n}\n\n/** \n * @deprecated use TIME_DAY_MS\n * Number of milliseconds in one calendar day (24 * 60 * 60 * 1000). */\nexport const DAY_MS = TIME_DAY_MS // 1000 * 60 * 60 * 24\n\n/** DayValue is a numeric date encoded as YYYYMMDD (for example 20250907). */\nexport type DayValue = number\n\n/**\n * Accepted inputs for day conversion helpers.\n * - DayValue or number: a YYYYMMDD numeric value\n * - string: a date string (parsed by digits)\n * - Date: JavaScript Date\n * - [year, month?, day?]: numeric parts\n */\nexport type DayInput =\n  | DayValue\n  | number\n  | string\n  | Date\n  | [number, number?, number?]\n\n/**\n * Extract the year (YYYY) from a DayValue.\n *\n * @param day - day as YYYYMMDD\n * @returns year as number (e.g. 2025)\n */\nexport function dayYear(day: DayValue): DayValue {\n  return Math.floor(day / 10000)\n}\n\n/**\n * Extract the month (1-12) from a DayValue.\n *\n * @param day - day as YYYYMMDD\n * @returns month number (1-12)\n */\nexport function dayMonth(day: DayValue): DayValue {\n  return Math.floor((day / 100) % 100)\n}\n\n/**\n * Extract the day of month (1-31) from a DayValue.\n *\n * @param day - day as YYYYMMDD\n * @returns day of month (1-31)\n */\nexport function dayDay(day: DayValue): DayValue {\n  return Math.floor(day % 100)\n}\n\n/**\n * Split a DayValue into [year, month, day].\n *\n * @param day - day as YYYYMMDD\n * @returns tuple [year, month, day]\n */\nexport function dayToParts(day: DayValue): [number, number, number] {\n  return [dayYear(day), dayMonth(day), dayDay(day)]\n}\n\n/**\n * Convert a DayValue to a JavaScript Date.\n *\n * By default returns a local Date at midnight for the day. If `utc` is true\n * the returned Date represents midnight UTC for that day.\n *\n * @param day - day as YYYYMMDD\n * @param utc - whether to construct the Date in UTC (default: false)\n * @returns Date object for the given day\n */\nexport function dayToDate(day: DayValue, utc = false): Date {\n  return utc\n    ? new Date(`${dayToString(day)}T00:00:00.000Z`)\n    : new Date(\n      day / 10000, // year\n      Math.max(0, ((day / 100) % 100) - 1), // month\n      Math.max(1, day % 100), // day\n    )\n}\n\n/**\n * Return today's day as a DayValue (YYYYMMDD).\n *\n * If test mode has been enabled via `setDayTest` this returns the forced\n * value instead. Otherwise it uses the current local date.\n */\nexport function dayFromToday(): DayValue {\n  return testModeDay ?? dayFromDate(new Date())\n}\n\n/**\n * Convert multiple input types to a DayValue (YYYYMMDD).\n *\n * Supports numbers (DayValue), strings, Date objects and [year, month?, day?]\n * tuples. Returns undefined for invalid or unsupported values.\n *\n * @param value - input to convert\n * @param utc - when converting from Date, interpret as UTC if true\n */\nexport function dayFromAny(\n  value: DayInput,\n  utc = false,\n): DayValue | undefined {\n  if (typeof value === 'number') {\n    if (value < 100)\n      return\n    return value\n  }\n  else if (typeof value === 'string') {\n    return dayFromString(value)\n  }\n  else if (Array.isArray(value) && value.length >= 1) {\n    return dayFromParts(...value)\n  }\n  else if (value instanceof Date) {\n    return dayFromDate(value, utc)\n    // } else if (value instanceof Day) {\n    //   return value.days\n  }\n}\n\n/** Convert a DayValue to a Date at midnight UTC. */\nexport function dayToDateUTC(day: DayValue): Date {\n  return dayToDate(day, true)\n}\n\n/**\n * @deprecated use dayToDateUTC\n *\n * Kept for backwards compatibility; returns a Date for midnight UTC.\n */\nexport function dayToDateGMT(day: DayValue): Date {\n  return dayToDate(day, true)\n}\n\n/**\n * Convert a JavaScript Date to a DayValue (YYYYMMDD).\n *\n * If `utc` is true the function uses the ISO string representation to\n * calculate the day in UTC. Otherwise it uses local date components.\n */\nexport function dayFromDate(date: Date, utc = false): DayValue {\n  return (\n    utc\n      ? dayFromString(date.toISOString())\n      : date.getFullYear() * 10000\n      + (date.getMonth() + 1) * 100\n      + date.getDate()\n  )!\n}\n\n/** Convert a Date to DayValue using UTC. */\nexport function dayFromDateUTC(date: Date): DayValue {\n  return dayFromDate(date, true)\n}\n\n/** @deprecated use dayFromDateUTC */\n/**\n * Deprecated: use `dayFromDateUTC`.\n *\n * Kept for backwards compatibility; converts a Date to a UTC DayValue.\n */\nexport function dayFromDateGMT(date: Date): DayValue {\n  return dayFromDate(date, true)\n}\n\n\n/**\n * Convert a DayValue to a UNIX timestamp in seconds. Returns seconds since\n * epoch for midnight of the given day. Defaults to UTC.\n */\nexport function dayToTimestampSeconds(day: DayValue, utc = true): number {\n  return Math.floor(dayToDate(day, utc).getTime() / 1000)\n}\n\n/**\n * Convert a DayValue to a timestamp in milliseconds for midnight of that day.\n * Defaults to UTC when constructing the Date.\n */\nexport function dayToTimestamp(day: DayValue, utc = true): number {\n  return dayToDate(day, utc).getTime()\n}\n\n/**\n * Convert a timestamp in milliseconds to a DayValue. The timestamp is turned\n * into a Date and then converted; `utc` controls interpretation.\n */\nexport function dayFromTimestamp(ms: number, utc = true): DayValue {\n  return dayFromDate(new Date(ms), utc)\n}\n\n/**\n * Convert a UNIX timestamp in seconds to a DayValue.\n *\n * @param ms - seconds since epoch\n */\nexport function dayFromTimestampSeconds(ms: number, utc = true): DayValue {\n  return dayFromDate(new Date(Math.floor(ms * 1000)), utc)\n}\n\n/**\n * Format a DayValue as a string with an optional separator.\n *\n * Example: dayToString(20250907) -> \"2025-09-07\"\n */\nexport function dayToString(day: DayValue, sep = '-') {\n  const baseString = String(day)\n  return (\n    baseString.slice(0, 4) + sep\n    + baseString.slice(4, 6) + sep\n    + baseString.slice(6, 8)\n  )\n}\n\n/**\n * Build a DayValue from numeric parts. Returns undefined for invalid parts.\n *\n * @param year - full year (e.g. 2025)\n * @param month - 1-12 (default 1)\n * @param day - 1-31 (default 1)\n */\nexport function dayFromParts(\n  year: number,\n  month = 1,\n  day = 1,\n): DayValue | undefined {\n  if (month < 1 || month > 12 || day < 1 || day > 31)\n    return\n  return year * 10000 + month * 100 + day\n}\n \n/**\n * Parse a string into a DayValue by extracting up to 8 digits (YYYYMMDD).\n * Returns undefined for invalid results.\n * \n * Example:\n * dayValue === dayFromString(String(dayValue))\n */\nexport function dayFromString(value: string): DayValue | undefined {\n  const string = String(value)\n    .replace(/\\D/g, '')\n    .slice(0, 8)\n  if (string.length === 8)\n    return +string\n}\n\n/**\n * Return the first day of the month for the given DayValue. An optional\n * `offset` (positive or negative) moves the result by months.\n *\n * @param day - source DayValue\n * @param offset - months to offset (default 0)\n */\nexport function dayMonthStart(day: DayValue, offset = 0): DayValue {\n  let year = dayYear(day)\n  let month = dayMonth(day)\n  if (offset !== 0) {\n    month += offset\n    year += Math.floor((month - 1) / 12)\n    month = Math.floor((month - 1) % 12) + 1\n    if (month === 0)\n      month = 12\n  }\n  return dayFromParts(year, month, 1)!\n}\n\n/**\n * Return the day offset by whole months, keeping the day-of-month when possible.\n * If the target month has fewer days, the result is clamped to the last day.\n *\n * @param day - source DayValue\n * @param offset - months to offset (positive or negative)\n */\nexport function dayMonthOffset(day: DayValue, offset: number): DayValue {\n  let year = dayYear(day)\n  let month = dayMonth(day)\n  const dayOfMonth = dayDay(day)\n\n  if (offset !== 0) {\n    month += offset\n    year += Math.floor((month - 1) / 12)\n    month = Math.floor((month - 1) % 12) + 1\n    if (month === 0)\n      month = 12\n  }\n\n  const maxDay = dayDaysInMonth(year, month)\n  return dayFromParts(year, month, Math.min(dayOfMonth, maxDay))!\n}\n\n/**\n * Return the first day of the year for the given DayValue. `offset` moves\n * the year by the given amount.\n */\nexport function dayYearStart(day: DayValue, offset = 0): DayValue {\n  const year = dayYear(day)\n  return dayFromParts(year + offset, 1, 1)!\n}\n\n/**\n * Return the day offset by whole years, keeping month and day when possible.\n * If the target month has fewer days, the result is clamped to the last day.\n *\n * @param day - source DayValue\n * @param offset - years to offset (positive or negative)\n */\nexport function dayYearOffset(day: DayValue, offset: number): DayValue {\n  const year = dayYear(day) + offset\n  const month = dayMonth(day)\n  const dayOfMonth = dayDay(day)\n  const maxDay = dayDaysInMonth(year, month)\n  return dayFromParts(year, month, Math.min(dayOfMonth, maxDay))!\n}\n\n/** Return number of days in a given month. Month is 1-12. */\nexport function dayDaysInMonth(year: number, month: number): number {\n  return new Date(Date.UTC(year, month, 0)).getUTCDate()\n}\n\n/**\n * Offset a DayValue by a number of days. Uses timestamp math to avoid local\n * DST issues.\n *\n * @param day - source DayValue\n * @param offset - days to add (negative to subtract)\n */\nexport function dayOffset(day: DayValue, offset: number): DayValue {\n  // Important! Don't use local time here due to summer/winter time days can\n  // be longer or shorter!\n  return dayFromTimestamp(dayToTimestamp(day) + offset * TIME_DAY_MS)\n}\n\n/**\n * Compute the difference in whole days between two DayValues (right - left).\n */\nexport function dayDiff(left: DayValue, right: DayValue): number {\n  return Math.round((dayToTimestamp(right) - dayToTimestamp(left)) / TIME_DAY_MS)\n}\n\n/**\n * Return an array of DayValues from left to right (inclusive).\n *\n * If `right` is omitted it defaults to today. If `left` is negative it is\n * interpreted as an offset relative to `right` (e.g. -7 means the last 7 days).\n */\nexport function dayRange(left: DayValue, right?: DayValue): number[] {\n  const list: number[] = []\n\n  if (right == null)\n    right = dayFromToday()\n\n  if (left < 0)\n    left = dayOffset(right, left + 1)\n\n  while (left <= right) {\n    list.push(left)\n    left = dayOffset(left, +1)\n  }\n  return list\n}\n\n/** Iterator, see dayRange */\n/**\n * Generator that yields DayValues from left to right (inclusive). Same rules\n * as `dayRange` regarding defaults and negative left values.\n */\nexport function* dayIterator(left: DayValue, right?: DayValue) {\n  const list: number[] = []\n\n  if (right == null)\n    right = dayFromToday()\n\n  if (left < 0)\n    left = dayOffset(right, left + 1)\n\n  while (left <= right) {\n    yield left\n    left = dayOffset(left, +1)\n  }\n  return list\n}\n\n"],"mappings":"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"}