UNPKG

chronobox

Version:

A TypeScript date manipulation library

1 lines 9.77 kB
{"version":3,"sources":["../src/errors.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["export class ChronoBoxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ChronoBoxError\";\n }\n}\n","import { TimeUnit } from \"./enums\";\n\nexport const isValidTimeUnit = (unit: any): unit is TimeUnit =>\n unit === TimeUnit.MILLISECONDS ||\n unit === TimeUnit.SECONDS ||\n unit === TimeUnit.MINUTES ||\n unit === TimeUnit.HOURS ||\n unit === TimeUnit.DAYS ||\n unit === TimeUnit.WEEKS ||\n unit === TimeUnit.MONTHS ||\n unit === TimeUnit.YEARS;\n","import type { CustomFormat, DateComponents, DateInput } from \"./types.d.ts\";\n\nimport { ChronoBoxError } from \"./errors\";\nimport { isValidTimeUnit } from \"./utils\";\nimport { DateFormat, TimeUnit } from \"./enums\";\n\nexport class ChronoBox<TFormat extends DateFormat | CustomFormat = DateFormat> {\n private readonly date: Date;\n private readonly format: TFormat;\n\n constructor(date?: DateInput, format: TFormat = DateFormat.ISO as TFormat) {\n this.format = format;\n\n try {\n this.date = date ? new Date(date) : new Date();\n if (isNaN(this.date.getTime())) {\n throw new ChronoBoxError(\"Invalid date input\");\n }\n } catch (error) {\n throw new ChronoBoxError(\n `Failed to parse date: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`\n );\n }\n }\n\n /**\n * Add a specified amount of time units to the date\n */\n add<T extends TimeUnit>(amount: number, unit: T): ChronoBox<TFormat> {\n const newDate = new Date(this.date);\n\n switch (unit) {\n case TimeUnit.MILLISECONDS:\n newDate.setMilliseconds(newDate.getMilliseconds() + amount);\n break;\n case TimeUnit.SECONDS:\n newDate.setSeconds(newDate.getSeconds() + amount);\n break;\n case TimeUnit.MINUTES:\n newDate.setMinutes(newDate.getMinutes() + amount);\n break;\n case TimeUnit.HOURS:\n newDate.setHours(newDate.getHours() + amount);\n break;\n case TimeUnit.DAYS:\n newDate.setDate(newDate.getDate() + amount);\n break;\n case TimeUnit.WEEKS:\n newDate.setDate(newDate.getDate() + amount * 7);\n break;\n case TimeUnit.MONTHS: {\n const dayOfMonth = newDate.getDate();\n newDate.setDate(1); // Temporarily set to the first of the month\n newDate.setMonth(newDate.getMonth() + amount);\n const maxDaysInNewMonth = new Date(\n newDate.getFullYear(),\n newDate.getMonth() + 1,\n 0\n ).getDate();\n newDate.setDate(Math.min(dayOfMonth, maxDaysInNewMonth));\n break;\n }\n case TimeUnit.YEARS: {\n const dayOfMonth = newDate.getDate();\n newDate.setDate(1); // Temporarily set to the first of the month\n newDate.setFullYear(newDate.getFullYear() + amount);\n const maxDaysInNewMonth = new Date(\n newDate.getFullYear(),\n newDate.getMonth() + 1,\n 0\n ).getDate();\n newDate.setDate(Math.min(dayOfMonth, maxDaysInNewMonth));\n break;\n }\n default:\n const _exhaustiveCheck: never = unit;\n throw new ChronoBoxError(`Unsupported time unit: ${unit}`);\n }\n\n return new ChronoBox<TFormat>(newDate, this.format);\n }\n\n /**\n * Subtract a specified amount of time units from the date\n */\n subtract<T extends TimeUnit>(amount: number, unit: T): ChronoBox<TFormat> {\n return this.add(-amount, unit);\n }\n\n /**\n * Get the difference between two dates in the specified unit\n */\n diff(other: DateInput, unit: TimeUnit = TimeUnit.DAYS): number {\n const otherDate = new Date(other);\n const diffMs = this.date.getTime() - otherDate.getTime();\n\n if (!isValidTimeUnit(unit)) {\n throw new ChronoBoxError(`Unsupported time unit: ${unit}`);\n }\n\n switch (unit) {\n case TimeUnit.MILLISECONDS:\n return diffMs;\n case TimeUnit.SECONDS:\n return diffMs / 1000;\n case TimeUnit.MINUTES:\n return diffMs / (1000 * 60);\n case TimeUnit.HOURS:\n return diffMs / (1000 * 60 * 60);\n case TimeUnit.DAYS:\n return diffMs / (1000 * 60 * 60 * 24);\n case TimeUnit.WEEKS:\n return diffMs / (1000 * 60 * 60 * 24 * 7);\n case TimeUnit.MONTHS:\n return (\n (this.date.getFullYear() - otherDate.getFullYear()) * 12 +\n (this.date.getMonth() - otherDate.getMonth())\n );\n case TimeUnit.YEARS:\n return this.date.getFullYear() - otherDate.getFullYear();\n default:\n const _exhaustiveCheck: never = unit;\n throw new ChronoBoxError(`Unsupported time unit: ${unit}`);\n }\n }\n\n /**\n * Get individual components of the date\n */\n getComponents(): DateComponents {\n return {\n year: this.date.getFullYear(),\n month: this.date.getMonth() + 1,\n day: this.date.getDate(),\n hours: this.date.getHours(),\n minutes: this.date.getMinutes(),\n seconds: this.date.getSeconds(),\n milliseconds: this.date.getMilliseconds(),\n };\n }\n\n /**\n * Format the date according to the format string\n */\n formatDate(): string {\n const components = this.getComponents();\n const monthNames = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ];\n\n let result = this.format;\n\n // Replace tokens with actual values\n return result\n .replace(\"YYYY\", components.year.toString())\n .replace(\"MMMM\", monthNames[components.month - 1])\n .replace(\"MM\", components.month.toString().padStart(2, \"0\"))\n .replace(\"DD\", components.day.toString().padStart(2, \"0\"));\n }\n\n /**\n * Check if the date is valid\n */\n isValid(): boolean {\n return !isNaN(this.date.getTime());\n }\n\n /**\n * Get the underlying Date object\n */\n toDate(): Date {\n return new Date(this.date);\n }\n\n /**\n * Create a new ChronoBox with a different format\n */\n withFormat<NewFormat extends DateFormat | CustomFormat>(\n newFormat: NewFormat\n ): ChronoBox<NewFormat> {\n return new ChronoBox<NewFormat>(this.date, newFormat);\n }\n}\n"],"mappings":"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","names":[]}