superjs-core 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/async/index.d.ts +84 -1
- package/dist/async/index.js +151 -0
- package/dist/async/index.js.map +1 -1
- package/dist/collection/index.d.ts +7 -1
- package/dist/collection/index.js +55 -0
- package/dist/collection/index.js.map +1 -1
- package/dist/date/index.d.ts +71 -1
- package/dist/date/index.js +121 -1
- package/dist/date/index.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/math/index.d.ts +59 -1
- package/dist/math/index.js +69 -0
- package/dist/math/index.js.map +1 -1
- package/dist/string/index.d.ts +41 -1
- package/dist/string/index.js +117 -0
- package/dist/string/index.js.map +1 -1
- package/package.json +1 -1
package/dist/date/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/date/index.ts"],"sourcesContent":["/**\r\n * Error thrown when a date value is invalid.\r\n */\r\nexport class InvalidDateError extends Error {\r\n constructor(input: unknown) {\r\n super(`Invalid date: ${String(input)}`)\r\n this.name = 'InvalidDateError'\r\n }\r\n}\r\n\r\nexport interface DateDiff {\r\n years: number\r\n months: number\r\n days: number\r\n hours: number\r\n minutes: number\r\n seconds: number\r\n}\r\n\r\nconst MONTH_NAMES_SHORT = [\r\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\r\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\r\n] as const\r\n\r\nconst MONTH_NAMES_FULL = [\r\n 'January', 'February', 'March', 'April', 'May', 'June',\r\n 'July', 'August', 'September', 'October', 'November', 'December',\r\n] as const\r\n\r\nconst MONTH_MAP: Record<string, number> = {\r\n jan: 0, january: 0,\r\n feb: 1, february: 1,\r\n mar: 2, march: 2,\r\n apr: 3, april: 3,\r\n may: 4,\r\n jun: 5, june: 5,\r\n jul: 6, july: 6,\r\n aug: 7, august: 7,\r\n sep: 8, september: 8,\r\n oct: 9, october: 9,\r\n nov: 10, november: 10,\r\n dec: 11, december: 11,\r\n}\r\n\r\n/**\r\n * Formats a Date to a string using the given format pattern.\r\n *\r\n * Supported tokens:\r\n * - `YYYY` — 4-digit year\r\n * - `YY` — 2-digit year\r\n * - `MMMM` — full month name\r\n * - `MMM` — abbreviated month name\r\n * - `MM` — 2-digit month (01–12)\r\n * - `DD` — 2-digit day (01–31)\r\n * - `HH` — 2-digit hours (00–23)\r\n * - `mm` — 2-digit minutes\r\n * - `ss` — 2-digit seconds\r\n * - `SSS` — milliseconds\r\n *\r\n * @param date - The date to format.\r\n * @param format - The format string (default `'YYYY-MM-DD'`).\r\n * @returns The formatted date string.\r\n */\r\nexport function formatDate(date: Date, format: string = 'YYYY-MM-DD'): string {\r\n const year = date.getFullYear()\r\n const month = date.getMonth()\r\n const day = date.getDate()\r\n const hours = date.getHours()\r\n const minutes = date.getMinutes()\r\n const seconds = date.getSeconds()\r\n const ms = date.getMilliseconds()\r\n\r\n const pad = (n: number, len: number = 2): string => String(n).padStart(len, '0')\r\n\r\n return format\r\n .replace(/YYYY/g, String(year))\r\n .replace(/YY/g, String(year).slice(-2))\r\n .replace(/MMMM/g, MONTH_NAMES_FULL[month]!)\r\n .replace(/MMM/g, MONTH_NAMES_SHORT[month]!)\r\n .replace(/MM/g, pad(month + 1))\r\n .replace(/DD/g, pad(day))\r\n .replace(/HH/g, pad(hours))\r\n .replace(/mm/g, pad(minutes))\r\n .replace(/ss/g, pad(seconds))\r\n .replace(/SSS/g, pad(ms, 3))\r\n}\r\n\r\n/**\r\n * Parses a date from a string, number (timestamp in ms), or Date object.\r\n *\r\n * Supported string formats:\r\n * - ISO (`YYYY-MM-DD`, `YYYY-MM-DDTHH:mm:ss`)\r\n * - `DD/MM/YYYY` or `DD-MM-YYYY`\r\n * - `DD MMM YYYY` or `DD MMMM YYYY`\r\n * - Unix timestamp (milliseconds)\r\n *\r\n * @param input - The value to parse.\r\n * @returns A valid Date object.\r\n * @throws {InvalidDateError} If the input cannot be parsed.\r\n */\r\nexport function parseDate(input: string | number | Date): Date {\r\n if (input instanceof Date) {\r\n if (isNaN(input.getTime())) throw new InvalidDateError(input)\r\n return new Date(input.getTime())\r\n }\r\n\r\n if (typeof input === 'number') {\r\n const d = new Date(input)\r\n if (isNaN(d.getTime())) throw new InvalidDateError(input)\r\n return d\r\n }\r\n\r\n const trimmed = input.trim()\r\n\r\n // ISO format: YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss\r\n const isoMatch = trimmed.match(/^(\\d{4})-(\\d{2})-(\\d{2})(?:T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/)\r\n if (isoMatch) {\r\n const d = new Date(\r\n parseInt(isoMatch[1]!, 10),\r\n parseInt(isoMatch[2]!, 10) - 1,\r\n parseInt(isoMatch[3]!, 10),\r\n isoMatch[4] ? parseInt(isoMatch[4]!, 10) : 0,\r\n isoMatch[5] ? parseInt(isoMatch[5]!, 10) : 0,\r\n isoMatch[6] ? parseInt(isoMatch[6]!, 10) : 0,\r\n isoMatch[7] ? parseInt(isoMatch[7]!.padEnd(3, '0'), 10) : 0\r\n )\r\n if (!isNaN(d.getTime())) return d\r\n }\r\n\r\n // DD/MM/YYYY or DD-MM-YYYY\r\n const dmyMatch = trimmed.match(/^(\\d{1,2})[\\/-](\\d{1,2})[\\/-](\\d{4})$/)\r\n if (dmyMatch) {\r\n const year = parseInt(dmyMatch[3]!, 10)\r\n const month = parseInt(dmyMatch[2]!, 10) - 1\r\n const day = parseInt(dmyMatch[1]!, 10)\r\n const d = new Date(year, month, day)\r\n // Validate that the date didn't overflow (e.g. Feb 29 in non-leap year)\r\n if (!isNaN(d.getTime()) && d.getMonth() === month && d.getDate() === day) return d\r\n }\r\n\r\n // DD MMM YYYY or DD MMMM YYYY\r\n const textMatch = trimmed.match(/^(\\d{1,2})\\s+([a-zA-Z]+)\\s+(\\d{4})$/)\r\n if (textMatch) {\r\n const monthIndex = MONTH_MAP[textMatch[2]!.toLowerCase()]\r\n if (monthIndex !== undefined) {\r\n const year = parseInt(textMatch[3]!, 10)\r\n const day = parseInt(textMatch[1]!, 10)\r\n const d = new Date(year, monthIndex, day)\r\n if (!isNaN(d.getTime()) && d.getMonth() === monthIndex && d.getDate() === day) return d\r\n }\r\n }\r\n\r\n // Unix timestamp (milliseconds) as string\r\n const numMatch = trimmed.match(/^-?\\d+$/)\r\n if (numMatch) {\r\n const d = new Date(parseInt(numMatch[0], 10))\r\n if (!isNaN(d.getTime())) return d\r\n }\r\n\r\n // Fallback: let Date.parse try\r\n const fallback = new Date(trimmed)\r\n if (!isNaN(fallback.getTime())) return fallback\r\n\r\n throw new InvalidDateError(input)\r\n}\r\n\r\nfunction isValidDate(d: Date): boolean {\r\n return d instanceof Date && !isNaN(d.getTime())\r\n}\r\n\r\nconst MS_IN_SECOND = 1000\r\nconst MS_IN_MINUTE = 60 * MS_IN_SECOND\r\nconst MS_IN_HOUR = 60 * MS_IN_MINUTE\r\nconst MS_IN_DAY = 24 * MS_IN_HOUR\r\n\r\n/**\r\n * Computes the difference between two dates.\r\n *\r\n * @param date1 - Start date.\r\n * @param date2 - End date.\r\n * @returns An object with years, months, days, hours, minutes, seconds.\r\n * @throws {InvalidDateError} If either date is invalid.\r\n */\r\nexport function dateDiff(date1: Date, date2: Date): DateDiff {\r\n if (!isValidDate(date1) || !isValidDate(date2)) {\r\n throw new InvalidDateError('Invalid date provided to dateDiff')\r\n }\r\n\r\n let years = date2.getFullYear() - date1.getFullYear()\r\n let months = date2.getMonth() - date1.getMonth()\r\n let days = date2.getDate() - date1.getDate()\r\n\r\n if (days < 0) {\r\n months -= 1\r\n const prevMonth = new Date(date2.getFullYear(), date2.getMonth(), 0)\r\n days += prevMonth.getDate()\r\n }\r\n\r\n if (months < 0) {\r\n years -= 1\r\n months += 12\r\n }\r\n\r\n const msDiff = Math.abs(date2.getTime() - date1.getTime())\r\n const totalSeconds = Math.floor(msDiff / MS_IN_SECOND)\r\n const hours = Math.floor((msDiff % MS_IN_DAY) / MS_IN_HOUR)\r\n const minutes = Math.floor((msDiff % MS_IN_HOUR) / MS_IN_MINUTE)\r\n const seconds = totalSeconds % 60\r\n\r\n return { years, months, days, hours, minutes, seconds }\r\n}\r\n\r\n/**\r\n * Adds days to a date.\r\n *\r\n * @param date - The original date.\r\n * @param days - Number of days to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addDays(date: Date, days: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const result = new Date(date.getTime())\r\n result.setDate(result.getDate() + days)\r\n return result\r\n}\r\n\r\n/**\r\n * Adds months to a date. Handles month-end overflow (e.g., Jan 31 + 1 month\r\n * becomes Feb 28).\r\n *\r\n * @param date - The original date.\r\n * @param months - Number of months to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addMonths(date: Date, months: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const result = new Date(date.getTime())\r\n const targetMonth = result.getMonth() + months\r\n result.setMonth(targetMonth)\r\n\r\n if (result.getMonth() !== ((targetMonth % 12) + 12) % 12) {\r\n result.setDate(0)\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * Adds years to a date. Handles leap-year overflow (e.g., Feb 29 + 1 year\r\n * becomes Feb 28).\r\n *\r\n * @param date - The original date.\r\n * @param years - Number of years to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addYears(date: Date, years: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const result = new Date(date.getTime())\r\n const targetYear = result.getFullYear() + years\r\n result.setFullYear(targetYear)\r\n\r\n if (result.getFullYear() !== targetYear) {\r\n result.setDate(0)\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * Returns the start of the day (00:00:00.000) for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to midnight.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function startOfDay(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0)\r\n}\r\n\r\n/**\r\n * Returns the end of the day (23:59:59.999) for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to the last millisecond of the day.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function endOfDay(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999)\r\n}\r\n\r\n/**\r\n * Returns the first moment of the month for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to the start of the month.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function startOfMonth(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0)\r\n}\r\n\r\n/**\r\n * Returns the last moment of the month for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to the end of the month.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function endOfMonth(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999)\r\n}\r\n\r\n/**\r\n * Returns the first moment of the year for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to Jan 1 00:00:00.000.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function startOfYear(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0)\r\n}\r\n\r\n/**\r\n * Returns the last moment of the year for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to Dec 31 23:59:59.999.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function endOfYear(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), 12, 0, 23, 59, 59, 999)\r\n}\r\n\r\n/**\r\n * Checks if the date falls on a weekend (Saturday or Sunday).\r\n *\r\n * @param date - The date to check.\r\n * @returns Whether the date is a weekend.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function isWeekend(date: Date): boolean {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const day = date.getDay()\r\n return day === 0 || day === 6\r\n}\r\n\r\n/**\r\n * Checks if a year is a leap year.\r\n *\r\n * @param year - The year to check.\r\n * @returns Whether the year is a leap year.\r\n */\r\nexport function isLeapYear(year: number): boolean {\r\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0\r\n}\r\n\r\n/**\r\n * Checks if `date1` is before `date2`.\r\n *\r\n * @param date1 - First date.\r\n * @param date2 - Second date.\r\n * @returns Whether `date1` is before `date2`.\r\n * @throws {InvalidDateError} If either date is invalid.\r\n */\r\nexport function isBefore(date1: Date, date2: Date): boolean {\r\n if (!isValidDate(date1) || !isValidDate(date2)) {\r\n throw new InvalidDateError('Invalid date provided to isBefore')\r\n }\r\n return date1.getTime() < date2.getTime()\r\n}\r\n\r\n/**\r\n * Checks if `date1` is after `date2`.\r\n *\r\n * @param date1 - First date.\r\n * @param date2 - Second date.\r\n * @returns Whether `date1` is after `date2`.\r\n * @throws {InvalidDateError} If either date is invalid.\r\n */\r\nexport function isAfter(date1: Date, date2: Date): boolean {\r\n if (!isValidDate(date1) || !isValidDate(date2)) {\r\n throw new InvalidDateError('Invalid date provided to isAfter')\r\n }\r\n return date1.getTime() > date2.getTime()\r\n}\r\n\r\n/**\r\n * Checks if a date is within the inclusive range [start, end].\r\n *\r\n * @param date - The date to check.\r\n * @param start - Start of the range.\r\n * @param end - End of the range.\r\n * @returns Whether the date is between start and end.\r\n * @throws {InvalidDateError} If any date is invalid.\r\n */\r\nexport function isBetween(date: Date, start: Date, end: Date): boolean {\r\n if (!isValidDate(date) || !isValidDate(start) || !isValidDate(end)) {\r\n throw new InvalidDateError('Invalid date provided to isBetween')\r\n }\r\n return date.getTime() >= start.getTime() && date.getTime() <= end.getTime()\r\n}\r\n\r\n/**\r\n * Checks if a date is a business day (Monday to Friday).\r\n *\r\n * @param date - The date to check.\r\n * @returns Whether the date is a business day.\r\n */\r\nexport function isBusinessDay(date: Date): boolean {\r\n return isValidDate(date) && !isWeekend(date)\r\n}\r\n\r\n/**\r\n * Adds business days (skipping weekends) to a date.\r\n *\r\n * @param date - The starting date.\r\n * @param days - Number of business days to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addBusinessDays(date: Date, days: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n\r\n const result = new Date(date.getTime())\r\n let remaining = Math.abs(days)\r\n const step = days >= 0 ? 1 : -1\r\n\r\n while (remaining > 0) {\r\n result.setDate(result.getDate() + step)\r\n const day = result.getDay()\r\n if (day !== 0 && day !== 6) {\r\n remaining--\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * Calculates age in years from a birth date.\r\n *\r\n * @param birthDate - The date of birth.\r\n * @returns The age in years.\r\n * @throws {InvalidDateError} If the birth date is invalid.\r\n */\r\nexport function calculateAge(birthDate: Date): number {\r\n if (!isValidDate(birthDate)) throw new InvalidDateError(birthDate)\r\n\r\n const today = new Date()\r\n let age = today.getFullYear() - birthDate.getFullYear()\r\n const monthDiff = today.getMonth() - birthDate.getMonth()\r\n\r\n if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {\r\n age--\r\n }\r\n\r\n return age\r\n}\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/date/index.ts"],"sourcesContent":["/**\r\n * Error thrown when a date value is invalid.\r\n */\r\nexport class InvalidDateError extends Error {\r\n constructor(input: unknown) {\r\n super(`Invalid date: ${String(input)}`)\r\n this.name = 'InvalidDateError'\r\n }\r\n}\r\n\r\nexport interface DateDiff {\r\n years: number\r\n months: number\r\n days: number\r\n hours: number\r\n minutes: number\r\n seconds: number\r\n}\r\n\r\nconst MONTH_NAMES_SHORT = [\r\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\r\n 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',\r\n] as const\r\n\r\nconst MONTH_NAMES_FULL = [\r\n 'January', 'February', 'March', 'April', 'May', 'June',\r\n 'July', 'August', 'September', 'October', 'November', 'December',\r\n] as const\r\n\r\nconst MONTH_MAP: Record<string, number> = {\r\n jan: 0, january: 0,\r\n feb: 1, february: 1,\r\n mar: 2, march: 2,\r\n apr: 3, april: 3,\r\n may: 4,\r\n jun: 5, june: 5,\r\n jul: 6, july: 6,\r\n aug: 7, august: 7,\r\n sep: 8, september: 8,\r\n oct: 9, october: 9,\r\n nov: 10, november: 10,\r\n dec: 11, december: 11,\r\n}\r\n\r\n/**\r\n * Formats a Date to a string using the given format pattern.\r\n *\r\n * Supported tokens:\r\n * - `YYYY` — 4-digit year\r\n * - `YY` — 2-digit year\r\n * - `MMMM` — full month name\r\n * - `MMM` — abbreviated month name\r\n * - `MM` — 2-digit month (01–12)\r\n * - `DD` — 2-digit day (01–31)\r\n * - `HH` — 2-digit hours (00–23)\r\n * - `mm` — 2-digit minutes\r\n * - `ss` — 2-digit seconds\r\n * - `SSS` — milliseconds\r\n *\r\n * @param date - The date to format.\r\n * @param format - The format string (default `'YYYY-MM-DD'`).\r\n * @returns The formatted date string.\r\n */\r\nexport function formatDate(date: Date, format: string = 'YYYY-MM-DD'): string {\r\n const year = date.getFullYear()\r\n const month = date.getMonth()\r\n const day = date.getDate()\r\n const hours = date.getHours()\r\n const minutes = date.getMinutes()\r\n const seconds = date.getSeconds()\r\n const ms = date.getMilliseconds()\r\n\r\n const pad = (n: number, len: number = 2): string => String(n).padStart(len, '0')\r\n\r\n return format\r\n .replace(/YYYY/g, String(year))\r\n .replace(/YY/g, String(year).slice(-2))\r\n .replace(/MMMM/g, MONTH_NAMES_FULL[month]!)\r\n .replace(/MMM/g, MONTH_NAMES_SHORT[month]!)\r\n .replace(/MM/g, pad(month + 1))\r\n .replace(/DD/g, pad(day))\r\n .replace(/HH/g, pad(hours))\r\n .replace(/mm/g, pad(minutes))\r\n .replace(/ss/g, pad(seconds))\r\n .replace(/SSS/g, pad(ms, 3))\r\n}\r\n\r\n/**\r\n * Parses a date from a string, number (timestamp in ms), or Date object.\r\n *\r\n * Supported string formats:\r\n * - ISO (`YYYY-MM-DD`, `YYYY-MM-DDTHH:mm:ss`)\r\n * - `DD/MM/YYYY` or `DD-MM-YYYY`\r\n * - `DD MMM YYYY` or `DD MMMM YYYY`\r\n * - Unix timestamp (milliseconds)\r\n *\r\n * @param input - The value to parse.\r\n * @returns A valid Date object.\r\n * @throws {InvalidDateError} If the input cannot be parsed.\r\n */\r\nexport function parseDate(input: string | number | Date): Date {\r\n if (input instanceof Date) {\r\n if (isNaN(input.getTime())) throw new InvalidDateError(input)\r\n return new Date(input.getTime())\r\n }\r\n\r\n if (typeof input === 'number') {\r\n const d = new Date(input)\r\n if (isNaN(d.getTime())) throw new InvalidDateError(input)\r\n return d\r\n }\r\n\r\n const trimmed = input.trim()\r\n\r\n // ISO format: YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss\r\n const isoMatch = trimmed.match(/^(\\d{4})-(\\d{2})-(\\d{2})(?:T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?)?(?:Z|[+-]\\d{2}:?\\d{2})?$/)\r\n if (isoMatch) {\r\n const d = new Date(\r\n parseInt(isoMatch[1]!, 10),\r\n parseInt(isoMatch[2]!, 10) - 1,\r\n parseInt(isoMatch[3]!, 10),\r\n isoMatch[4] ? parseInt(isoMatch[4]!, 10) : 0,\r\n isoMatch[5] ? parseInt(isoMatch[5]!, 10) : 0,\r\n isoMatch[6] ? parseInt(isoMatch[6]!, 10) : 0,\r\n isoMatch[7] ? parseInt(isoMatch[7]!.padEnd(3, '0'), 10) : 0\r\n )\r\n if (!isNaN(d.getTime())) return d\r\n }\r\n\r\n // DD/MM/YYYY or DD-MM-YYYY\r\n const dmyMatch = trimmed.match(/^(\\d{1,2})[\\/-](\\d{1,2})[\\/-](\\d{4})$/)\r\n if (dmyMatch) {\r\n const year = parseInt(dmyMatch[3]!, 10)\r\n const month = parseInt(dmyMatch[2]!, 10) - 1\r\n const day = parseInt(dmyMatch[1]!, 10)\r\n const d = new Date(year, month, day)\r\n // Validate that the date didn't overflow (e.g. Feb 29 in non-leap year)\r\n if (!isNaN(d.getTime()) && d.getMonth() === month && d.getDate() === day) return d\r\n }\r\n\r\n // DD MMM YYYY or DD MMMM YYYY\r\n const textMatch = trimmed.match(/^(\\d{1,2})\\s+([a-zA-Z]+)\\s+(\\d{4})$/)\r\n if (textMatch) {\r\n const monthIndex = MONTH_MAP[textMatch[2]!.toLowerCase()]\r\n if (monthIndex !== undefined) {\r\n const year = parseInt(textMatch[3]!, 10)\r\n const day = parseInt(textMatch[1]!, 10)\r\n const d = new Date(year, monthIndex, day)\r\n if (!isNaN(d.getTime()) && d.getMonth() === monthIndex && d.getDate() === day) return d\r\n }\r\n }\r\n\r\n // Unix timestamp (milliseconds) as string\r\n const numMatch = trimmed.match(/^-?\\d+$/)\r\n if (numMatch) {\r\n const d = new Date(parseInt(numMatch[0], 10))\r\n if (!isNaN(d.getTime())) return d\r\n }\r\n\r\n // Fallback: let Date.parse try\r\n const fallback = new Date(trimmed)\r\n if (!isNaN(fallback.getTime())) return fallback\r\n\r\n throw new InvalidDateError(input)\r\n}\r\n\r\nfunction isValidDate(d: Date): boolean {\r\n return d instanceof Date && !isNaN(d.getTime())\r\n}\r\n\r\nconst MS_IN_SECOND = 1000\r\nconst MS_IN_MINUTE = 60 * MS_IN_SECOND\r\nconst MS_IN_HOUR = 60 * MS_IN_MINUTE\r\nconst MS_IN_DAY = 24 * MS_IN_HOUR\r\n\r\n/**\r\n * Computes the difference between two dates.\r\n *\r\n * @param date1 - Start date.\r\n * @param date2 - End date.\r\n * @returns An object with years, months, days, hours, minutes, seconds.\r\n * @throws {InvalidDateError} If either date is invalid.\r\n */\r\nexport function dateDiff(date1: Date, date2: Date): DateDiff {\r\n if (!isValidDate(date1) || !isValidDate(date2)) {\r\n throw new InvalidDateError('Invalid date provided to dateDiff')\r\n }\r\n\r\n let years = date2.getFullYear() - date1.getFullYear()\r\n let months = date2.getMonth() - date1.getMonth()\r\n let days = date2.getDate() - date1.getDate()\r\n\r\n if (days < 0) {\r\n months -= 1\r\n const prevMonth = new Date(date2.getFullYear(), date2.getMonth(), 0)\r\n days += prevMonth.getDate()\r\n }\r\n\r\n if (months < 0) {\r\n years -= 1\r\n months += 12\r\n }\r\n\r\n const msDiff = Math.abs(date2.getTime() - date1.getTime())\r\n const totalSeconds = Math.floor(msDiff / MS_IN_SECOND)\r\n const hours = Math.floor((msDiff % MS_IN_DAY) / MS_IN_HOUR)\r\n const minutes = Math.floor((msDiff % MS_IN_HOUR) / MS_IN_MINUTE)\r\n const seconds = totalSeconds % 60\r\n\r\n return { years, months, days, hours, minutes, seconds }\r\n}\r\n\r\n/**\r\n * Adds days to a date.\r\n *\r\n * @param date - The original date.\r\n * @param days - Number of days to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addDays(date: Date, days: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const result = new Date(date.getTime())\r\n result.setDate(result.getDate() + days)\r\n return result\r\n}\r\n\r\n/**\r\n * Adds months to a date. Handles month-end overflow (e.g., Jan 31 + 1 month\r\n * becomes Feb 28).\r\n *\r\n * @param date - The original date.\r\n * @param months - Number of months to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addMonths(date: Date, months: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const result = new Date(date.getTime())\r\n const targetMonth = result.getMonth() + months\r\n result.setMonth(targetMonth)\r\n\r\n if (result.getMonth() !== ((targetMonth % 12) + 12) % 12) {\r\n result.setDate(0)\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * Adds years to a date. Handles leap-year overflow (e.g., Feb 29 + 1 year\r\n * becomes Feb 28).\r\n *\r\n * @param date - The original date.\r\n * @param years - Number of years to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addYears(date: Date, years: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const result = new Date(date.getTime())\r\n const targetYear = result.getFullYear() + years\r\n result.setFullYear(targetYear)\r\n\r\n if (result.getFullYear() !== targetYear) {\r\n result.setDate(0)\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * Returns the start of the day (00:00:00.000) for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to midnight.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function startOfDay(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0)\r\n}\r\n\r\n/**\r\n * Returns the end of the day (23:59:59.999) for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to the last millisecond of the day.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function endOfDay(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999)\r\n}\r\n\r\n/**\r\n * Returns the first moment of the month for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to the start of the month.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function startOfMonth(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0)\r\n}\r\n\r\n/**\r\n * Returns the last moment of the month for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to the end of the month.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function endOfMonth(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999)\r\n}\r\n\r\n/**\r\n * Returns the first moment of the year for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to Jan 1 00:00:00.000.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function startOfYear(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0)\r\n}\r\n\r\n/**\r\n * Returns the last moment of the year for the given date.\r\n *\r\n * @param date - The date.\r\n * @returns A new Date set to Dec 31 23:59:59.999.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function endOfYear(date: Date): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n return new Date(date.getFullYear(), 12, 0, 23, 59, 59, 999)\r\n}\r\n\r\n/**\r\n * Checks if the date falls on a weekend (Saturday or Sunday).\r\n *\r\n * @param date - The date to check.\r\n * @returns Whether the date is a weekend.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function isWeekend(date: Date): boolean {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const day = date.getDay()\r\n return day === 0 || day === 6\r\n}\r\n\r\n/**\r\n * Checks if a year is a leap year.\r\n *\r\n * @param year - The year to check.\r\n * @returns Whether the year is a leap year.\r\n */\r\nexport function isLeapYear(year: number): boolean {\r\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0\r\n}\r\n\r\n/**\r\n * Checks if `date1` is before `date2`.\r\n *\r\n * @param date1 - First date.\r\n * @param date2 - Second date.\r\n * @returns Whether `date1` is before `date2`.\r\n * @throws {InvalidDateError} If either date is invalid.\r\n */\r\nexport function isBefore(date1: Date, date2: Date): boolean {\r\n if (!isValidDate(date1) || !isValidDate(date2)) {\r\n throw new InvalidDateError('Invalid date provided to isBefore')\r\n }\r\n return date1.getTime() < date2.getTime()\r\n}\r\n\r\n/**\r\n * Checks if `date1` is after `date2`.\r\n *\r\n * @param date1 - First date.\r\n * @param date2 - Second date.\r\n * @returns Whether `date1` is after `date2`.\r\n * @throws {InvalidDateError} If either date is invalid.\r\n */\r\nexport function isAfter(date1: Date, date2: Date): boolean {\r\n if (!isValidDate(date1) || !isValidDate(date2)) {\r\n throw new InvalidDateError('Invalid date provided to isAfter')\r\n }\r\n return date1.getTime() > date2.getTime()\r\n}\r\n\r\n/**\r\n * Checks if a date is within the inclusive range [start, end].\r\n *\r\n * @param date - The date to check.\r\n * @param start - Start of the range.\r\n * @param end - End of the range.\r\n * @returns Whether the date is between start and end.\r\n * @throws {InvalidDateError} If any date is invalid.\r\n */\r\nexport function isBetween(date: Date, start: Date, end: Date): boolean {\r\n if (!isValidDate(date) || !isValidDate(start) || !isValidDate(end)) {\r\n throw new InvalidDateError('Invalid date provided to isBetween')\r\n }\r\n return date.getTime() >= start.getTime() && date.getTime() <= end.getTime()\r\n}\r\n\r\n/**\r\n * Checks if a date is a business day (Monday to Friday).\r\n *\r\n * @param date - The date to check.\r\n * @returns Whether the date is a business day.\r\n */\r\nexport function isBusinessDay(date: Date): boolean {\r\n return isValidDate(date) && !isWeekend(date)\r\n}\r\n\r\n/**\r\n * Adds business days (skipping weekends) to a date.\r\n *\r\n * @param date - The starting date.\r\n * @param days - Number of business days to add (negative to subtract).\r\n * @returns A new Date.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function addBusinessDays(date: Date, days: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n\r\n const result = new Date(date.getTime())\r\n let remaining = Math.abs(days)\r\n const step = days >= 0 ? 1 : -1\r\n\r\n while (remaining > 0) {\r\n result.setDate(result.getDate() + step)\r\n const day = result.getDay()\r\n if (day !== 0 && day !== 6) {\r\n remaining--\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * Calculates age in years from a birth date.\r\n *\r\n * @param birthDate - The date of birth.\r\n * @returns The age in years.\r\n * @throws {InvalidDateError} If the birth date is invalid.\r\n */\r\nexport function calculateAge(birthDate: Date): number {\r\n if (!isValidDate(birthDate)) throw new InvalidDateError(birthDate)\r\n\r\n const today = new Date()\r\n let age = today.getFullYear() - birthDate.getFullYear()\r\n const monthDiff = today.getMonth() - birthDate.getMonth()\r\n\r\n if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {\r\n age--\r\n }\r\n\r\n return age\r\n}\r\n\r\n// ─── Time Ago & Time Remaining ───────────────────────────────────────────────\r\n\r\ninterface LocaleLabels {\r\n years: { single: string; plural: string }\r\n months: { single: string; plural: string }\r\n weeks: { single: string; plural: string }\r\n days: { single: string; plural: string }\r\n hours: { single: string; plural: string }\r\n minutes: { single: string; plural: string }\r\n seconds: { single: string; plural: string }\r\n}\r\n\r\nconst LOCALE_LABELS: Record<string, LocaleLabels> = {\r\n id: {\r\n years: { single: 'tahun', plural: 'tahun' },\r\n months: { single: 'bulan', plural: 'bulan' },\r\n weeks: { single: 'minggu', plural: 'minggu' },\r\n days: { single: 'hari', plural: 'hari' },\r\n hours: { single: 'jam', plural: 'jam' },\r\n minutes: { single: 'menit', plural: 'menit' },\r\n seconds: { single: 'detik', plural: 'detik' },\r\n },\r\n en: {\r\n years: { single: 'year', plural: 'years' },\r\n months: { single: 'month', plural: 'months' },\r\n weeks: { single: 'week', plural: 'weeks' },\r\n days: { single: 'day', plural: 'days' },\r\n hours: { single: 'hour', plural: 'hours' },\r\n minutes: { single: 'minute', plural: 'minutes' },\r\n seconds: { single: 'second', plural: 'seconds' },\r\n },\r\n}\r\n\r\nfunction getSuffix(diffMs: number, kind: 'ago' | 'remaining', locale: string): string {\r\n if (diffMs < 0) {\r\n return locale === 'en' ? 'ago' : 'yang lalu'\r\n }\r\n if (kind === 'remaining') {\r\n return locale === 'en' ? 'remaining' : 'lagi'\r\n }\r\n return locale === 'en' ? 'ago' : 'yang lalu'\r\n}\r\n\r\nfunction formatRelativeTime(absDiffMs: number, suffix: string, locale: string): string {\r\n const labels = LOCALE_LABELS[locale] ?? LOCALE_LABELS.id!\r\n\r\n const seconds = Math.floor(absDiffMs / 1000)\r\n const minutes = Math.floor(seconds / 60)\r\n const hours = Math.floor(minutes / 60)\r\n const days = Math.floor(hours / 24)\r\n const weeks = Math.floor(days / 7)\r\n const months = Math.floor(days / 30.4375)\r\n const years = Math.floor(days / 365.25)\r\n\r\n let count: number\r\n let unit: keyof LocaleLabels\r\n\r\n if (years >= 1) { count = years; unit = 'years' }\r\n else if (months >= 1) { count = months; unit = 'months' }\r\n else if (weeks >= 1) { count = weeks; unit = 'weeks' }\r\n else if (days >= 1) { count = days; unit = 'days' }\r\n else if (hours >= 1) { count = hours; unit = 'hours' }\r\n else if (minutes >= 1) { count = minutes; unit = 'minutes' }\r\n else { count = Math.max(1, seconds); unit = 'seconds' }\r\n\r\n const label = count === 1 ? labels[unit].single : labels[unit].plural\r\n return `${count} ${label} ${suffix}`\r\n}\r\n\r\n/**\r\n * Returns a human-readable relative time string (e.g. \"5 menit yang lalu\").\r\n *\r\n * @param date - The past date.\r\n * @param options - Options with locale ('id' by default, 'en' supported).\r\n * @returns A relative time string.\r\n */\r\nexport function timeAgo(date: Date, options?: { locale?: string }): string {\r\n const diff = Date.now() - date.getTime()\r\n const locale = options?.locale ?? 'id'\r\n const suffix = getSuffix(diff, 'ago', locale)\r\n return formatRelativeTime(Math.abs(diff), suffix, locale)\r\n}\r\n\r\n/**\r\n * Shows the time remaining until a future date.\r\n *\r\n * @param target - The target future date.\r\n * @param options - Options with locale ('id' by default, 'en' supported).\r\n * @returns A relative time string.\r\n */\r\nexport function timeRemaining(target: Date, options?: { locale?: string }): string {\r\n const diff = target.getTime() - Date.now()\r\n const locale = options?.locale ?? 'id'\r\n const suffix = getSuffix(diff, 'remaining', locale)\r\n return formatRelativeTime(Math.abs(diff), suffix, locale)\r\n}\r\n\r\n// ─── Duration ────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Represents a duration split into calendar and time components.\r\n */\r\nexport interface Duration {\r\n years: number\r\n months: number\r\n days: number\r\n hours: number\r\n minutes: number\r\n seconds: number\r\n}\r\n\r\n/**\r\n * Formats a Duration object into a human-readable string.\r\n *\r\n * @example\r\n * formatDuration({ hours: 2, minutes: 30, seconds: 15 }) // \"2 jam 30 menit 15 detik\"\r\n * formatDuration({ hours: 2, minutes: 30 }, { locale: 'en' }) // \"2 hours 30 minutes\"\r\n *\r\n * @param duration - The duration to format.\r\n * @param options - Options with locale ('id' by default, 'en' supported).\r\n * @returns A formatted duration string.\r\n */\r\nexport function formatDuration(duration: Duration, options?: { locale?: string }): string {\r\n const locale = options?.locale ?? 'id'\r\n const labels = LOCALE_LABELS[locale] ?? LOCALE_LABELS.id!\r\n\r\n const parts: string[] = []\r\n const entries: [keyof Duration, number][] = [\r\n ['years', duration.years],\r\n ['months', duration.months],\r\n ['days', duration.days],\r\n ['hours', duration.hours],\r\n ['minutes', duration.minutes],\r\n ['seconds', duration.seconds],\r\n ]\r\n\r\n for (const [key, value] of entries) {\r\n if (value > 0) {\r\n const label = value === 1 ? labels[key].single : labels[key].plural\r\n parts.push(`${value} ${label}`)\r\n }\r\n }\r\n\r\n if (parts.length === 0) {\r\n const label = labels.seconds.plural\r\n return `0 ${label}`\r\n }\r\n\r\n return parts.join(' ')\r\n}\r\n\r\n// ─── Timezone Helpers ────────────────────────────────────────────────────────\r\n\r\n/** UTC+7 — Western Indonesia Time (WIB). */\r\nexport const TIMEZONE_WIB = 7\r\n\r\n/** UTC+8 — Central Indonesia Time (WITA). */\r\nexport const TIMEZONE_WITA = 8\r\n\r\n/** UTC+9 — Eastern Indonesia Time (WIT). */\r\nexport const TIMEZONE_WIT = 9\r\n\r\n/**\r\n * Converts a date to a specific timezone offset by returning a new Date whose\r\n * local-time getters (getHours, getMinutes etc.) reflect the target timezone.\r\n *\r\n * @param date - The source date.\r\n * @param offsetHours - The timezone offset in hours (e.g. 7 for WIB).\r\n * @returns A new Date adjusted to the target timezone.\r\n * @throws {InvalidDateError} If the input date is invalid.\r\n */\r\nexport function toTimezone(date: Date, offsetHours: number): Date {\r\n if (!isValidDate(date)) throw new InvalidDateError(date)\r\n const utcMs = date.getTime() + date.getTimezoneOffset() * 60000\r\n return new Date(utcMs + offsetHours * 3600000)\r\n}\r\n\r\n/**\r\n * Formats a date in a specific timezone using `formatDate` tokens.\r\n *\r\n * @param date - The source date.\r\n * @param format - The format string (see `formatDate` for supported tokens).\r\n * @param offsetHours - The timezone offset in hours.\r\n * @returns The formatted date string.\r\n */\r\nexport function formatInTimezone(date: Date, format: string, offsetHours: number): string {\r\n return formatDate(toTimezone(date, offsetHours), format)\r\n}\r\n"],"mappings":"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","names":[]}
|