/** * Represents dates with values ranging from January 1, 0001 Anno Domini (Common Era) * through December 31, 9999 A.D. (C.E.) in the Gregorian calendar. * * DateOnly provides date-only functionality without time components, making it ideal * for scenarios where only the date portion is relevant (birthdays, deadlines, etc.). * * @example * // Create DateOnly instances * const today = new DateOnly(2024, 12, 25); * const fromDayNumber = DateOnly.fromDayNumber(738500); * const fromDate = DateOnly.fromDate(new Date()); * * // Date arithmetic * const tomorrow = today.addDays(1); * const nextMonth = today.addMonths(1); * const nextYear = today.addYears(1); * * // Comparisons * console.log(today.equals(tomorrow)); // false * console.log(today.compareTo(tomorrow)); // -1 * * // Formatting * console.log(today.toString()); // "2024-12-25" */ export default class DateOnly { /** @private */ private static "__#7@#MIN_DAY_NUMBER"; /** @private */ private static "__#7@#MAX_DAY_NUMBER"; /** @private */ private static "__#7@#TICKS_PER_DAY"; /** * Private constructor that creates DateOnly from day number directly. * @private * @param {number} dayNumber - The day number (0 to MAX_DAY_NUMBER) */ private static "__#7@#fromDayNumber"; /** * Creates a DateOnly instance from the specified day number. * * @param {number} dayNumber - The number of days since January 1, 0001 in the Proleptic Gregorian calendar * @returns {DateOnly} A new DateOnly instance representing the specified day * @throws {RangeError} If dayNumber is out of valid range (0 to 3652058) * * @example * const date = DateOnly.fromDayNumber(738500); // Represents a specific date * console.log(date.toString()); // Outputs the corresponding date string */ static fromDayNumber(dayNumber: number): DateOnly; /** * Converts date components to day number. * * @private * @param {number} year - The year * @param {number} month - The month * @param {number} day - The day * @returns {number} The day number representing the date */ private static "__#7@#dateToTicks"; /** * Calculates the number of days from year 1 to the beginning of the specified year. * * @private * @param {number} year - The year * @returns {number} Number of days from year 1 to the start of the specified year */ private static "__#7@#daysToYear"; /** * Gets the number of days in the specified month. * * @private * @param {number} year - The year * @param {number} month - The month (1-12) * @returns {number} Number of days in the month */ private static "__#7@#getDaysInMonth"; /** * Gets the number of days from the beginning of the year to the beginning of the specified month. * * @private * @param {number} year - The year * @param {number} month - The month (1-12) * @returns {number} Number of days from beginning of year to beginning of month */ private static "__#7@#getDaysToMonth"; /** * Converts day number back to year, month, day components. * This is used internally for property getters. * * @private * @param {number} dayNumber - The day number * @returns {{year: number, month: number, day: number}} Date components */ private static "__#7@#dayNumberToDate"; /** * Determines whether the specified year is a leap year. * * A leap year is divisible by 4, except for years divisible by 100 unless they are also divisible by 400. * * @param {number} year - The year to check (1 through 9999) * @returns {boolean} true if the year is a leap year; otherwise, false * @throws {RangeError} If year is out of valid range * * @example * DateOnly.isLeapYear(2024); // true (divisible by 4) * DateOnly.isLeapYear(1900); // false (divisible by 100 but not 400) * DateOnly.isLeapYear(2000); // true (divisible by 400) */ static isLeapYear(year: number): boolean; /** * Creates a DateOnly instance from a JavaScript Date object. * * Only the date components (year, month, day) are used; time components are ignored. * * @param {Date} date - The JavaScript Date object to convert * @returns {DateOnly} A new DateOnly instance representing the date portion of the input Date * @throws {TypeError} If the input is not a Date object * * @example * const jsDate = new Date(2024, 11, 25, 15, 30, 45); // December 25, 2024 3:30:45 PM * const dateOnly = DateOnly.fromDate(jsDate); * console.log(dateOnly.toString()); // "2024-12-25" (time ignored) */ static fromDate(date: Date): DateOnly; /** * Creates a DateOnly instance from a DateTime object. * * Only the date components are extracted; time components are ignored. * * @param {DateTime} dateTime - The DateTime object to convert * @returns {DateOnly} A new DateOnly instance representing the date portion of the DateTime * @throws {TypeError} If the input is not a DateTime object * * @example * // Assuming DateTime is imported * const dateTime = new DateTime(2024, 12, 25, 15, 30, 45); * const dateOnly = DateOnly.fromDateTime(dateTime); * console.log(dateOnly.toString()); // "2024-12-25" */ static fromDateTime(dateTime: DateTime): DateOnly; /** * Gets the earliest possible DateOnly value (January 1, 0001). * * @type {DateOnly} * @readonly * @static * @example * const minDate = DateOnly.minValue; * console.log(minDate.toString()); // "0001-01-01" */ static readonly get minValue(): DateOnly; /** * Gets the latest possible DateOnly value (December 31, 9999). * * @type {DateOnly} * @readonly * @static * @example * const maxDate = DateOnly.maxValue; * console.log(maxDate.toString()); // "9999-12-31" */ static readonly get maxValue(): DateOnly; /** * Compares two DateOnly instances. * * @param {DateOnly} d1 - The first DateOnly instance * @param {DateOnly} d2 - The second DateOnly instance * @returns {number} * - Less than 0 if d1 is earlier than d2 * - 0 if d1 equals d2 * - Greater than 0 if d1 is later than d2 * * @example * const date1 = new DateOnly(2024, 12, 24); * const date2 = new DateOnly(2024, 12, 25); * * console.log(DateOnly.compare(date1, date2)); // -1 * console.log(DateOnly.compare(date2, date1)); // 1 * console.log(DateOnly.compare(date1, date1)); // 0 */ static compare(d1: DateOnly, d2: DateOnly): number; /** * Parses a string representation of a date and returns a DateOnly instance. * * The string must be in ISO 8601 format (YYYY-MM-DD). * * @param {string} s - The string to parse * @returns {DateOnly} A DateOnly instance representing the parsed date * @throws {TypeError} If the input is not a string * @throws {Error} If the string format is invalid * @throws {RangeError} If the date components are out of valid range * * @example * const date1 = DateOnly.parse("2024-12-25"); * const date2 = DateOnly.parse("2024-02-29"); // Valid leap year date * * // These will throw errors: * // DateOnly.parse("25-12-2024"); // Wrong format * // DateOnly.parse("2024-13-01"); // Invalid month * // DateOnly.parse("2023-02-29"); // Invalid leap day */ static parse(s: string): DateOnly; /** * Attempts to parse a string representation of a date and returns the result. * * Unlike parse(), this method does not throw exceptions on invalid input. * * @param {string} s - The string to parse * @returns {{success: boolean, value: DateOnly|null}} * An object containing: * - success: true if parsing succeeded, false otherwise * - value: The parsed DateOnly instance if successful, null otherwise * * @example * const result1 = DateOnly.tryParse("2024-12-25"); * if (result1.success) { * console.log(result1.value.toString()); // "2024-12-25" * } * * const result2 = DateOnly.tryParse("invalid-date"); * console.log(result2.success); // false * console.log(result2.value); // null */ static tryParse(s: string): { success: boolean; value: DateOnly | null; }; /** * Creates a new DateOnly instance. * * @param {number} year - The year (1 through 9999) * @param {number} month - The month (1 through 12) * @param {number} day - The day (1 through the number of days in the specified month) * @throws {RangeError} If any parameter is out of valid range * @throws {RangeError} If the day is invalid for the specified month and year * * @example * const date = new DateOnly(2024, 12, 25); // December 25, 2024 * const leapDay = new DateOnly(2024, 2, 29); // Valid leap year date */ constructor(year: number, month: number, day: number); /** * Gets the year component of the date represented by this instance. * * @type {number} * @readonly * @example * const date = new DateOnly(2024, 12, 25); * console.log(date.year); // 2024 */ readonly get year(): number; /** * Gets the month component of the date represented by this instance. * * @type {number} * @readonly * @example * const date = new DateOnly(2024, 12, 25); * console.log(date.month); // 12 */ readonly get month(): number; /** * Gets the day component of the date represented by this instance. * * @type {number} * @readonly * @example * const date = new DateOnly(2024, 12, 25); * console.log(date.day); // 25 */ readonly get day(): number; /** * Gets the day of the week represented by this instance. * * @type {number} * @readonly * @example * const date = new DateOnly(2024, 12, 25); * console.log(date.dayOfWeek); // 3 (Wednesday, where Sunday = 0) */ readonly get dayOfWeek(): number; /** * Gets the day of the year represented by this instance. * * @type {number} * @readonly * @example * const date = new DateOnly(2024, 12, 25); * console.log(date.dayOfYear); // 360 (the 360th day of 2024) */ readonly get dayOfYear(): number; /** * Gets the number of days since January 1, 0001 in the Proleptic Gregorian calendar * represented by this instance. * * @type {number} * @readonly * @example * const date = new DateOnly(2024, 1, 1); * console.log(date.dayNumber); // Number of days since year 1 */ readonly get dayNumber(): number; /** * Adds the specified number of days to the value of this instance. * * @param {number} value - The number of days to add. Can be negative to subtract days * @returns {DateOnly} A new DateOnly instance with the specified number of days added * @throws {RangeError} If the resulting date would be out of valid range * @throws {TypeError} If value is not a number * * @example * const date = new DateOnly(2024, 12, 25); * const nextDay = date.addDays(1); // December 26, 2024 * const prevDay = date.addDays(-1); // December 24, 2024 * const nextWeek = date.addDays(7); // January 1, 2025 */ addDays(value: number): DateOnly; /** * Adds the specified number of months to the value of this instance. * * If the resulting day is invalid for the target month (e.g., adding 1 month to January 31 * would result in February 31), the day is adjusted to the last valid day of that month. * * @param {number} months - The number of months to add. Can be negative to subtract months * @returns {DateOnly} A new DateOnly instance with the specified number of months added * @throws {RangeError} If months parameter is out of range (-120000 to 120000) * @throws {RangeError} If the resulting year would be out of valid range * @throws {TypeError} If months is not a number * * @example * const date = new DateOnly(2024, 1, 31); * const nextMonth = date.addMonths(1); // February 29, 2024 (adjusted from Feb 31) * const prevMonth = date.addMonths(-1); // December 31, 2023 * const nextYear = date.addMonths(12); // January 31, 2025 */ addMonths(months: number): DateOnly; /** * Adds the specified number of years to the value of this instance. * * If the current date is February 29 (leap day) and the target year is not a leap year, * the resulting date will be February 28. * * @param {number} years - The number of years to add. Can be negative to subtract years * @returns {DateOnly} A new DateOnly instance with the specified number of years added * @throws {RangeError} If years parameter is out of range (-10000 to 10000) * @throws {RangeError} If the resulting year would be out of valid range (1 to 9999) * @throws {TypeError} If years is not a number * * @example * const date = new DateOnly(2024, 2, 29); // Leap day * const nextYear = date.addYears(1); // February 28, 2025 (not a leap year) * const prevYear = date.addYears(-1); // February 28, 2023 (not a leap year) * const nextLeapYear = date.addYears(4); // February 29, 2028 (leap year) */ addYears(years: number): DateOnly; /** * Determines whether this DateOnly instance is equal to another DateOnly instance. * * @param {DateOnly} other - The DateOnly instance to compare with * @returns {boolean} true if both instances represent the same date; otherwise, false * * @example * const date1 = new DateOnly(2024, 12, 25); * const date2 = new DateOnly(2024, 12, 25); * const date3 = new DateOnly(2024, 12, 26); * * console.log(date1.equals(date2)); // true * console.log(date1.equals(date3)); // false */ equals(other: DateOnly): boolean; /** * Compares this DateOnly instance to another DateOnly instance. * * @param {DateOnly} other - The DateOnly instance to compare with * @returns {number} * - Less than 0 if this instance is earlier than other * - 0 if this instance is equal to other * - Greater than 0 if this instance is later than other * @throws {TypeError} If other is not a DateOnly instance * * @example * const date1 = new DateOnly(2024, 12, 24); * const date2 = new DateOnly(2024, 12, 25); * const date3 = new DateOnly(2024, 12, 26); * * console.log(date1.compareTo(date2)); // -1 (date1 is earlier) * console.log(date2.compareTo(date2)); // 0 (same date) * console.log(date3.compareTo(date2)); // 1 (date3 is later) */ compareTo(other: DateOnly): number; /** * Comparison operators as methods (since JavaScript doesn't support operator overloading) */ /** * Returns true if this date is less than the other date. * @param {DateOnly} other - The date to compare with * @returns {boolean} */ isLessThan(other: DateOnly): boolean; /** * Returns true if this date is less than or equal to the other date. * @param {DateOnly} other - The date to compare with * @returns {boolean} */ isLessThanOrEqual(other: DateOnly): boolean; /** * Returns true if this date is greater than the other date. * @param {DateOnly} other - The date to compare with * @returns {boolean} */ isGreaterThan(other: DateOnly): boolean; /** * Returns true if this date is greater than or equal to the other date. * @param {DateOnly} other - The date to compare with * @returns {boolean} */ isGreaterThanOrEqual(other: DateOnly): boolean; /** * Converts the DateOnly to its string representation in ISO 8601 format (YYYY-MM-DD). * * @returns {string} A string representation of the date in YYYY-MM-DD format * * @example * const date = new DateOnly(2024, 12, 25); * console.log(date.toString()); // "2024-12-25" * * const date2 = new DateOnly(2024, 1, 5); * console.log(date2.toString()); // "2024-01-05" */ toString(): string; /** * Combines this DateOnly with a time to create a JavaScript Date object. * * @param {number} [hours=0] - The hour component (0-23) * @param {number} [minutes=0] - The minute component (0-59) * @param {number} [seconds=0] - The second component (0-59) * @param {number} [milliseconds=0] - The millisecond component (0-999) * @param {boolean} [useUtc=false] - Whether to create a UTC date or local date * @returns {Date} A JavaScript Date object combining this date with the specified time * * @example * const dateOnly = new DateOnly(2024, 12, 25); * const localDate = dateOnly.toDate(10, 30, 0); // 10:30 AM local time * const utcDate = dateOnly.toDate(10, 30, 0, 0, true); // 10:30 AM UTC */ toDate(hours?: number, minutes?: number, seconds?: number, milliseconds?: number, useUtc?: boolean): Date; /** * Combines this DateOnly with a TimeOnly to create a DateTime object. * * @param {TimeOnly} time - The TimeOnly instance to combine with this date * @param {number} [kind] - Optional DateTimeKind for the resulting DateTime * @returns {DateTime} A DateTime object combining this date with the specified time * @throws {TypeError} If time is not a TimeOnly instance * * @example * // Assuming TimeOnly and DateTime are available * const dateOnly = new DateOnly(2024, 12, 25); * const timeOnly = new TimeOnly(10, 30, 0); * const dateTime = dateOnly.toDateTime(timeOnly); * console.log(dateTime.toString()); // "2024-12-25 10:30:00" */ toDateTime(time: TimeOnly, kind?: number): DateTime; /** * Returns the primitive value of the DateOnly instance (day number). * * This method is called automatically when the DateOnly is used in contexts * that require a primitive value, such as arithmetic operations or comparisons. * * @returns {number} The day number representing this date * * @example * const date = new DateOnly(2024, 12, 25); * console.log(+date); // Outputs the day number * console.log(date.valueOf()); // Same as above */ valueOf(): number; #private; } import TimeOnly from "./TimeOnly.js"; import DateTime from "./DateTime.js";