{
  "version": 3,
  "sources": ["../../src/date-time/utils.ts"],
  "sourcesContent": ["/**\n * External dependencies\n */\nimport { UTCDateMini } from '@date-fns/utc';\n\n/**\n * WordPress dependencies\n */\nimport { date as formatDate, getDate } from '@wordpress/date';\n\n/**\n * Internal dependencies\n */\n\nimport { COMMIT, PRESS_DOWN, PRESS_UP } from '../input-control/reducer/actions';\n\n/**\n * Converts a date input to a UTC-normalized date for consistent date\n * manipulation. Timezoneless strings are interpreted using the timezone\n * offset from @wordpress/date settings. Date objects and timestamps\n * represent specific UTC instants.\n *\n * @param input Value to turn into a date.\n */\nexport function inputToDate(input) {\n  if (typeof input === 'string') {\n    // Note that JavaScript doesn't fully support ISO-8601 time strings, so\n    // the behavior of passing these through to the Date constructor is\n    // non-deterministic.\n    //\n    // See: https://tc39.es/ecma262/#sec-date-time-string-format\n    const hasTimezone = /Z|[+-]\\d{2}(:?\\d{2})?$/.test(input);\n    if (hasTimezone) {\n      return new UTCDateMini(new Date(input));\n    }\n\n    // Strings without timezone indicators are interpreted using configured\n    // timezone offset, then converted to UTC for internal storage.\n    return new UTCDateMini(getDate(input).getTime());\n  }\n\n  // Date objects and number timestamps represent specific UTC moments.\n  // Convert to milliseconds since epoch for consistent UTC handling.\n  const time = input instanceof Date ? input.getTime() : input;\n  return new UTCDateMini(time);\n}\n\n/**\n * Returns the start of day (midnight) as a browser-local Date for the calendar\n * day in the configured timezone in @wordpress/date settings. This is necessary\n * because date-fns's startOfDay operates in browser local time, which can cause\n * off-by-one-day bugs when browser and configured timezones differ.\n *\n * For example, if the UTC time is Nov 16, 01:00 UTC and configured timezone\n * is UTC-5, the date is Nov 15. This function returns a browser-local Date\n * at Nov 15, 00:00 (browser local midnight) so it matches calendar days.\n *\n * @param date A Date object normalized to UTC\n * @return A browser-local Date at midnight for the configured timezone date\n */\nexport function startOfDayInConfiguredTimezone(date) {\n  // Determine the calendar day in the configured WordPress timezone and\n  // return a browser-local Date at midnight for that calendar day.\n  const year = Number(formatDate('Y', date));\n  const month = Number(formatDate('n', date)) - 1;\n  const day = Number(formatDate('j', date));\n  return new Date(year, month, day, 0, 0, 0, 0);\n}\n\n/**\n * Converts a 12-hour time to a 24-hour time.\n * @param hours\n * @param isPm\n */\nexport function from12hTo24h(hours, isPm) {\n  return isPm ? (hours % 12 + 12) % 24 : hours % 12;\n}\n\n/**\n * Converts a 24-hour time to a 12-hour time.\n * @param hours\n */\nexport function from24hTo12h(hours) {\n  return hours % 12 || 12;\n}\n\n/**\n * Creates an InputControl reducer used to pad an input so that it is always a\n * given width. For example, the hours and minutes inputs are padded to 2 so\n * that '4' appears as '04'.\n *\n * @param pad How many digits the value should be.\n */\nexport function buildPadInputStateReducer(pad) {\n  return (state, action) => {\n    const nextState = {\n      ...state\n    };\n    if (action.type === COMMIT || action.type === PRESS_UP || action.type === PRESS_DOWN) {\n      if (nextState.value !== undefined) {\n        nextState.value = nextState.value.toString().padStart(pad, '0');\n      }\n    }\n    return nextState;\n  };\n}\n\n/**\n * Returns the number of days in a month.\n *\n * @param year  The year\n * @param month The month, zero-indexed (0-11)\n *\n * @return The number of days in the month\n */\nexport const getDaysInMonth = (year, month) =>\n// Take advantage of JavaScript's built-in date wrapping logic, where day 0\n// of the next month is interpreted as the last day of the preceding month.\nnew Date(year, month + 1, 0).getDate();\n\n/**\n * Updates specific date fields in the configured timezone and returns a new\n * UTC date.\n *\n * @param date    A Date object\n * @param updates Object with fields to update\n * @return A Date object normalized to UTC with the updated values\n */\nexport function setInConfiguredTimezone(date, updates) {\n  const values = {\n    year: Number(formatDate('Y', date)),\n    month: Number(formatDate('n', date)) - 1,\n    date: Number(formatDate('j', date)),\n    hours: Number(formatDate('H', date)),\n    minutes: Number(formatDate('i', date)),\n    seconds: Number(formatDate('s', date)),\n    ...updates\n  };\n\n  // Clamp the day to the last valid day of the month, to avoid producing\n  // invalid date strings (e.g. \"2026-02-31\").\n  const daysInMonth = getDaysInMonth(values.year, values.month);\n  values.date = Math.min(values.date, daysInMonth);\n  const year = String(values.year).padStart(4, '0');\n  const month = String(values.month + 1).padStart(2, '0');\n  const day = String(values.date).padStart(2, '0');\n  const hours = String(values.hours).padStart(2, '0');\n  const minutes = String(values.minutes).padStart(2, '0');\n  const seconds = String(values.seconds).padStart(2, '0');\n  const timezoneless = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;\n\n  // Parse as WordPress-configured timezone time and convert to a UTC instant.\n  return new UTCDateMini(getDate(timezoneless).getTime());\n}\n\n/**\n * Validates the target of a React event to ensure it is an input element and\n * that the input is valid.\n * @param event\n */\nexport function validateInputElementTarget(event) {\n  // `instanceof` checks need to get the instance definition from the\n  // corresponding window object \u2014 therefore, the following logic makes\n  // the component work correctly even when rendered inside an iframe.\n  const HTMLInputElementInstance = event.target?.ownerDocument.defaultView?.HTMLInputElement ?? HTMLInputElement;\n  if (!(event.target instanceof HTMLInputElementInstance)) {\n    return false;\n  }\n  return event.target.validity.valid;\n}"],
  "mappings": "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",
  "names": ["formatDate"]
}
