{"version":3,"file":"time.mjs","sources":["../../../src/lib/utils/time.ts"],"sourcesContent":["/**\n * @file Time Utilities\n * @description Date/time formatting and manipulation utilities\n */\n\n/**\n * Format options\n */\nexport interface FormatOptions {\n  locale?: string;\n  timeZone?: string;\n}\n\n/**\n * Default format options\n */\nconst defaultFormatOptions: FormatOptions = {\n  locale: 'en-US',\n  timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n};\n\n/**\n * Parse date input to Date object\n */\nexport function parseDate(input: string | number | Date): Date {\n  if (input instanceof Date) {\n    return input;\n  }\n\n  if (typeof input === 'number') {\n    return new Date(input);\n  }\n\n  const parsed = new Date(input);\n  if (isNaN(parsed.getTime())) {\n    throw new Error(`Invalid date: ${input}`);\n  }\n\n  return parsed;\n}\n\n/**\n * Format date with pattern\n */\nexport function formatDate(\n  date: string | number | Date,\n  pattern: 'short' | 'medium' | 'long' | 'full' = 'medium',\n  options?: FormatOptions\n): string {\n  const d = parseDate(date);\n  const opts = { ...defaultFormatOptions, ...options };\n\n  const formats: Record<string, Intl.DateTimeFormatOptions> = {\n    short: { month: 'numeric', day: 'numeric', year: '2-digit' },\n    medium: { month: 'short', day: 'numeric', year: 'numeric' },\n    long: { month: 'long', day: 'numeric', year: 'numeric' },\n    full: { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' },\n  };\n\n  return new Intl.DateTimeFormat(opts.locale, {\n    ...formats[pattern],\n    timeZone: opts.timeZone,\n  }).format(d);\n}\n\n/**\n * Format time\n */\nexport function formatTime(\n  date: string | number | Date,\n  pattern: 'short' | 'medium' | 'long' = 'short',\n  options?: FormatOptions\n): string {\n  const d = parseDate(date);\n  const opts = { ...defaultFormatOptions, ...options };\n\n  const formats: Record<string, Intl.DateTimeFormatOptions> = {\n    short: { hour: 'numeric', minute: '2-digit' },\n    medium: { hour: 'numeric', minute: '2-digit', second: '2-digit' },\n    long: { hour: 'numeric', minute: '2-digit', second: '2-digit', timeZoneName: 'short' },\n  };\n\n  return new Intl.DateTimeFormat(opts.locale, {\n    ...formats[pattern],\n    timeZone: opts.timeZone,\n  }).format(d);\n}\n\n/**\n * Format date and time\n */\nexport function formatDateTime(\n  date: string | number | Date,\n  datePattern: 'short' | 'medium' | 'long' = 'medium',\n  timePattern: 'short' | 'medium' | 'long' = 'short',\n  options?: FormatOptions\n): string {\n  return `${formatDate(date, datePattern, options)} ${formatTime(date, timePattern, options)}`;\n}\n\n/**\n * Format relative time\n */\nexport function formatRelative(date: string | number | Date, options?: FormatOptions): string {\n  const d = parseDate(date);\n  const now = new Date();\n  const opts = { ...defaultFormatOptions, ...options };\n\n  const diffMs = now.getTime() - d.getTime();\n  const diffSec = Math.floor(diffMs / 1000);\n  const diffMin = Math.floor(diffSec / 60);\n  const diffHour = Math.floor(diffMin / 60);\n  const diffDay = Math.floor(diffHour / 24);\n  const diffWeek = Math.floor(diffDay / 7);\n  const diffMonth = Math.floor(diffDay / 30);\n  const diffYear = Math.floor(diffDay / 365);\n\n  const rtf = new Intl.RelativeTimeFormat(opts.locale, { numeric: 'auto' });\n\n  if (Math.abs(diffSec) < 60) {\n    return rtf.format(-Math.sign(diffMs) * Math.abs(diffSec), 'second');\n  }\n  if (Math.abs(diffMin) < 60) {\n    return rtf.format(-diffMin, 'minute');\n  }\n  if (Math.abs(diffHour) < 24) {\n    return rtf.format(-diffHour, 'hour');\n  }\n  if (Math.abs(diffDay) < 7) {\n    return rtf.format(-diffDay, 'day');\n  }\n  if (Math.abs(diffWeek) < 4) {\n    return rtf.format(-diffWeek, 'week');\n  }\n  if (Math.abs(diffMonth) < 12) {\n    return rtf.format(-diffMonth, 'month');\n  }\n\n  return rtf.format(-diffYear, 'year');\n}\n\n/**\n * Format duration\n */\nexport function formatDuration(ms: number, options?: { verbose?: boolean }): string {\n  const verbose = options?.verbose ?? false;\n\n  const seconds = Math.floor(ms / 1000);\n  const minutes = Math.floor(seconds / 60);\n  const hours = Math.floor(minutes / 60);\n  const days = Math.floor(hours / 24);\n\n  if (verbose) {\n    const parts: string[] = [];\n\n    if (days > 0) parts.push(`${days} day${days !== 1 ? 's' : ''}`);\n    if (hours % 24 > 0) parts.push(`${hours % 24} hour${hours % 24 !== 1 ? 's' : ''}`);\n    if (minutes % 60 > 0) parts.push(`${minutes % 60} minute${minutes % 60 !== 1 ? 's' : ''}`);\n    if (seconds % 60 > 0 && days === 0)\n      parts.push(`${seconds % 60} second${seconds % 60 !== 1 ? 's' : ''}`);\n\n    return parts.join(', ') || '0 seconds';\n  }\n\n  if (days > 0) {\n    return `${days}d ${hours % 24}h`;\n  }\n  if (hours > 0) {\n    return `${hours}h ${minutes % 60}m`;\n  }\n  if (minutes > 0) {\n    return `${minutes}m ${seconds % 60}s`;\n  }\n\n  return `${seconds}s`;\n}\n\n/**\n * Check if date is today\n */\nexport function isToday(date: string | number | Date): boolean {\n  const d = parseDate(date);\n  const today = new Date();\n\n  return (\n    d.getDate() === today.getDate() &&\n    d.getMonth() === today.getMonth() &&\n    d.getFullYear() === today.getFullYear()\n  );\n}\n\n/**\n * Check if date is yesterday\n */\nexport function isYesterday(date: string | number | Date): boolean {\n  const d = parseDate(date);\n  const yesterday = new Date();\n  yesterday.setDate(yesterday.getDate() - 1);\n\n  return (\n    d.getDate() === yesterday.getDate() &&\n    d.getMonth() === yesterday.getMonth() &&\n    d.getFullYear() === yesterday.getFullYear()\n  );\n}\n\n/**\n * Check if date is within the last N days\n */\nexport function isWithinDays(date: string | number | Date, days: number): boolean {\n  const d = parseDate(date);\n  const threshold = new Date();\n  threshold.setDate(threshold.getDate() - days);\n\n  return d >= threshold;\n}\n\n/**\n * Get start of day\n */\nexport function startOfDay(date: string | number | Date): Date {\n  const d = parseDate(date);\n  d.setHours(0, 0, 0, 0);\n  return d;\n}\n\n/**\n * Get end of day\n */\nexport function endOfDay(date: string | number | Date): Date {\n  const d = parseDate(date);\n  d.setHours(23, 59, 59, 999);\n  return d;\n}\n\n/**\n * Add time to date\n */\nexport function addTime(\n  date: string | number | Date,\n  amount: number,\n  unit: 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years'\n): Date {\n  const d = parseDate(date);\n\n  switch (unit) {\n    case 'seconds':\n      d.setSeconds(d.getSeconds() + amount);\n      break;\n    case 'minutes':\n      d.setMinutes(d.getMinutes() + amount);\n      break;\n    case 'hours':\n      d.setHours(d.getHours() + amount);\n      break;\n    case 'days':\n      d.setDate(d.getDate() + amount);\n      break;\n    case 'weeks':\n      d.setDate(d.getDate() + amount * 7);\n      break;\n    case 'months':\n      d.setMonth(d.getMonth() + amount);\n      break;\n    case 'years':\n      d.setFullYear(d.getFullYear() + amount);\n      break;\n  }\n\n  return d;\n}\n\n/**\n * Get difference between dates\n */\nexport function dateDiff(\n  date1: string | number | Date,\n  date2: string | number | Date,\n  unit: 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years'\n): number {\n  const d1 = parseDate(date1);\n  const d2 = parseDate(date2);\n  const diffMs = d2.getTime() - d1.getTime();\n\n  switch (unit) {\n    case 'seconds':\n      return Math.floor(diffMs / 1000);\n    case 'minutes':\n      return Math.floor(diffMs / (1000 * 60));\n    case 'hours':\n      return Math.floor(diffMs / (1000 * 60 * 60));\n    case 'days':\n      return Math.floor(diffMs / (1000 * 60 * 60 * 24));\n    case 'weeks':\n      return Math.floor(diffMs / (1000 * 60 * 60 * 24 * 7));\n    case 'months':\n      return (d2.getFullYear() - d1.getFullYear()) * 12 + (d2.getMonth() - d1.getMonth());\n    case 'years':\n      return d2.getFullYear() - d1.getFullYear();\n  }\n}\n"],"names":["defaultFormatOptions","parseDate","input","parsed","formatDate","date","pattern","options","d","opts","formats","formatTime","formatDateTime","datePattern","timePattern","formatRelative","now","diffMs","diffSec","diffMin","diffHour","diffDay","diffWeek","diffMonth","diffYear","rtf","formatDuration","ms","verbose","seconds","minutes","hours","days","parts","isToday","today","isYesterday","yesterday","isWithinDays","threshold","startOfDay","endOfDay","addTime","amount","unit","dateDiff","date1","date2","d1","d2"],"mappings":"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"}