UNPKG

universal-common

Version:

Library that provides useful missing base class library functionality.

469 lines (468 loc) 19.3 kB
/** * Represents a time of day, as would be read from a clock, within the range 00:00:00 to 23:59:59.9999999. * * TimeOnly provides time-only functionality without date components, making it ideal * for scenarios where only the time portion is relevant (schedules, opening hours, etc.). * * @example * // Create TimeOnly instances * const morning = new TimeOnly(9, 30); // 09:30:00 * const precise = new TimeOnly(14, 15, 30, 500); // 14:15:30.500 * const fromTicks = new TimeOnly(450000000000); // From ticks * * // Time arithmetic * const later = morning.addHours(2.5); // 12:00:00 * const duration = later.subtract(morning); // 2:30:00 TimeSpan * * // Comparisons and ranges * console.log(morning.isBetween(new TimeOnly(8, 0), new TimeOnly(17, 0))); // true * * // Formatting * console.log(morning.toString()); // "09:30:00" * console.log(precise.toString()); // "14:15:30.5" */ export default class TimeOnly { /** @private @type {bigint} Minimum time ticks (midnight) */ private static "__#6@#MIN_TIME_TICKS"; /** @private @type {bigint} Maximum time ticks (23:59:59.9999999) */ private static "__#6@#MAX_TIME_TICKS"; /** * Converts time components to ticks. * * @private * @param {number} hour - Hour component (0-23) * @param {number} minute - Minute component (0-59) * @param {number} second - Second component (0-59) * @param {number} millisecond - Millisecond component (0-999) * @returns {bigint} Total ticks representing the time * @throws {RangeError} If any component is out of valid range */ private static "__#6@#timeToTicks"; /** * Constructs a TimeOnly object from a TimeSpan representing the time elapsed since midnight. * * @param {TimeSpan} timeSpan - The time interval measured since midnight. This value has to be positive and not exceeding 24 hours * @returns {TimeOnly} A TimeOnly object representing the time elapsed since midnight using the timeSpan value * @throws {TypeError} If timeSpan is not a TimeSpan instance * @throws {RangeError} If timeSpan is negative or exceeds 24 hours * * @example * const span = TimeSpan.fromHours(14.5); // 14 hours 30 minutes * const time = TimeOnly.fromTimeSpan(span); * console.log(time.toString()); // "14:30:00" */ static fromTimeSpan(timeSpan: TimeSpan): TimeOnly; /** * Constructs a TimeOnly object from a DateTime representing the time of the day in this DateTime object. * * @param {DateTime} dateTime - The DateTime object to extract the time of the day from * @returns {TimeOnly} A TimeOnly object representing time of the day specified in the DateTime object * @throws {TypeError} If dateTime is not a DateTime instance * * @example * const dateTime = new DateTime(2024, 12, 25, 14, 30, 45); * const timeOnly = TimeOnly.fromDateTime(dateTime); * console.log(timeOnly.toString()); // "14:30:45" */ static fromDateTime(dateTime: DateTime): TimeOnly; /** * Gets the smallest possible value of TimeOnly (00:00:00.0000000). * * @type {TimeOnly} * @readonly * @static * * @example * const minTime = TimeOnly.minValue; * console.log(minTime.toString()); // "00:00:00" */ static readonly get minValue(): TimeOnly; /** * Gets the largest possible value of TimeOnly (23:59:59.9999999). * * @type {TimeOnly} * @readonly * @static * * @example * const maxTime = TimeOnly.maxValue; * console.log(maxTime.toString()); // "23:59:59.9999999" */ static readonly get maxValue(): TimeOnly; /** * Compares two TimeOnly values and returns an indication of their relative values. * * @param {TimeOnly} t1 - The first TimeOnly * @param {TimeOnly} t2 - The second TimeOnly * @returns {number} -1 if t1 is earlier than t2, 0 if equal, 1 if t1 is later than t2 * * @example * const morning = new TimeOnly(9, 0, 0); * const evening = new TimeOnly(17, 0, 0); * * console.log(TimeOnly.compare(morning, evening)); // -1 * console.log(TimeOnly.compare(evening, morning)); // 1 * console.log(TimeOnly.compare(morning, morning)); // 0 */ static compare(t1: TimeOnly, t2: TimeOnly): number; /** * Parses a string representation of a time and returns a TimeOnly instance. * * The string can be in various formats: * - "HH:mm" (e.g., "14:30") * - "HH:mm:ss" (e.g., "14:30:45") * - "HH:mm:ss.fff" (e.g., "14:30:45.123") * - "HH:mm:ss.fffffff" (e.g., "14:30:45.1234567") * * @param {string} s - The string to parse * @returns {TimeOnly} A TimeOnly instance representing the parsed time * @throws {TypeError} If the input is not a string * @throws {ArgumentError} If the string format is invalid * @throws {RangeError} If the time components are out of valid range * * @example * const time1 = TimeOnly.parse("14:30"); // 14:30:00 * const time2 = TimeOnly.parse("09:15:30"); // 09:15:30 * const time3 = TimeOnly.parse("16:45:30.500"); // 16:45:30.5 */ static parse(s: string): TimeOnly; /** * Attempts to parse a string representation of a time 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: TimeOnly|null}} * An object containing: * - success: true if parsing succeeded, false otherwise * - value: The parsed TimeOnly instance if successful, null otherwise * * @example * const result1 = TimeOnly.tryParse("14:30:45"); * if (result1.success) { * console.log(result1.value.toString()); // "14:30:45" * } * * const result2 = TimeOnly.tryParse("invalid-time"); * console.log(result2.success); // false * console.log(result2.value); // null */ static tryParse(s: string): { success: boolean; value: TimeOnly | null; }; /** * Creates a new TimeOnly instance. * * @constructor * @param {...number} args - Constructor arguments in various formats: * - (ticks) - 100-nanosecond intervals since midnight * - (hour, minute) - Hour and minute components * - (hour, minute, second) - Hour, minute, and second components * - (hour, minute, second, millisecond) - With milliseconds * - (hour, minute, second, millisecond, microsecond) - With microseconds * * @throws {ArgumentError} If invalid number of arguments provided * @throws {RangeError} If time components are out of valid range * * @example * // From ticks * const time1 = new TimeOnly(450000000000); // 12:30:00 * * // From hour and minute * const time2 = new TimeOnly(14, 30); // 14:30:00 * * // From hour, minute, second * const time3 = new TimeOnly(9, 15, 45); // 09:15:45 * * // With milliseconds * const time4 = new TimeOnly(16, 30, 0, 500); // 16:30:00.500 */ constructor(...args: number[]); /** * Gets the hour component of the time represented by this instance (0-23). * * @type {number} * @readonly * @example * const time = new TimeOnly(14, 30, 45); * console.log(time.hour); // 14 */ readonly get hour(): number; /** * Gets the minute component of the time represented by this instance (0-59). * * @type {number} * @readonly * @example * const time = new TimeOnly(14, 30, 45); * console.log(time.minute); // 30 */ readonly get minute(): number; /** * Gets the second component of the time represented by this instance (0-59). * * @type {number} * @readonly * @example * const time = new TimeOnly(14, 30, 45); * console.log(time.second); // 45 */ readonly get second(): number; /** * Gets the millisecond component of the time represented by this instance (0-999). * * @type {number} * @readonly * @example * const time = new TimeOnly(14, 30, 45, 500); * console.log(time.millisecond); // 500 */ readonly get millisecond(): number; /** * Gets the microsecond component of the time represented by this instance (0-999). * * @type {number} * @readonly * @example * const time = new TimeOnly(14, 30, 45, 500, 250); * console.log(time.microsecond); // 250 */ readonly get microsecond(): number; /** * Gets the nanosecond component of the time represented by this instance (0-900). * Note: Resolution is limited to 100-nanosecond intervals. * * @type {number} * @readonly */ readonly get nanosecond(): number; /** * Gets the number of ticks that represent the time of this instance. * * @type {number} * @readonly */ readonly get ticks(): number; /** * Returns a new TimeOnly that adds the value of the specified TimeSpan to the value of this instance. * * @param {TimeSpan} value - A positive or negative time interval * @returns {TimeOnly} An object whose value is the sum of the time represented by this instance and the time interval represented by value * @throws {TypeError} If value is not a TimeSpan * * @example * const morning = new TimeOnly(9, 0, 0); * const duration = TimeSpan.fromHours(2.5); * const later = morning.add(duration); // 11:30:00 */ add(value: TimeSpan): TimeOnly; /** * Returns a new TimeOnly that adds the value of the specified TimeSpan to the value of this instance. * If the result wraps past the end of the day, this method will return the number of excess days. * * @param {TimeSpan} value - A positive or negative time interval * @returns {{time: TimeOnly, wrappedDays: number}} Object containing the new time and wrapped days * @throws {TypeError} If value is not a TimeSpan * * @example * const evening = new TimeOnly(22, 0, 0); * const duration = TimeSpan.fromHours(4); * const result = evening.addWithWrappedDays(duration); * console.log(result.time.toString()); // "02:00:00" * console.log(result.wrappedDays); // 1 */ addWithWrappedDays(value: TimeSpan): { time: TimeOnly; wrappedDays: number; }; /** * Returns a new TimeOnly that adds the specified number of hours to the value of this instance. * * @param {number} value - A number of whole and fractional hours. The value parameter can be negative or positive * @returns {TimeOnly} An object whose value is the sum of the time represented by this instance and the number of hours represented by value * * @example * const time = new TimeOnly(10, 30, 0); * const later = time.addHours(2.5); // 13:00:00 */ addHours(value: number): TimeOnly; /** * Returns a new TimeOnly that adds the specified number of hours to the value of this instance. * If the result wraps past the end of the day, this method will return the number of excess days. * * @param {number} value - A number of whole and fractional hours. The value parameter can be negative or positive * @returns {{time: TimeOnly, wrappedDays: number}} Object containing the new time and wrapped days * * @example * const time = new TimeOnly(22, 0, 0); * const result = time.addHoursWithWrappedDays(4); * console.log(result.time.toString()); // "02:00:00" * console.log(result.wrappedDays); // 1 */ addHoursWithWrappedDays(value: number): { time: TimeOnly; wrappedDays: number; }; /** * Returns a new TimeOnly that adds the specified number of minutes to the value of this instance. * * @param {number} value - A number of whole and fractional minutes. The value parameter can be negative or positive * @returns {TimeOnly} An object whose value is the sum of the time represented by this instance and the number of minutes represented by value * * @example * const time = new TimeOnly(10, 30, 0); * const later = time.addMinutes(45); // 11:15:00 */ addMinutes(value: number): TimeOnly; /** * Returns a new TimeOnly that adds the specified number of minutes to the value of this instance. * If the result wraps past the end of the day, this method will return the number of excess days. * * @param {number} value - A number of whole and fractional minutes. The value parameter can be negative or positive * @returns {{time: TimeOnly, wrappedDays: number}} Object containing the new time and wrapped days * * @example * const time = new TimeOnly(23, 30, 0); * const result = time.addMinutesWithWrappedDays(45); * console.log(result.time.toString()); // "00:15:00" * console.log(result.wrappedDays); // 1 */ addMinutesWithWrappedDays(value: number): { time: TimeOnly; wrappedDays: number; }; /** * Determines if a time falls within the range provided. * Supports both "normal" ranges such as 10:00-12:00, and ranges that span midnight such as 23:00-01:00. * * @param {TimeOnly} start - The starting time of day, inclusive * @param {TimeOnly} end - The ending time of day, exclusive * @returns {boolean} True, if the time falls within the range, false otherwise * @throws {TypeError} If start or end is not a TimeOnly instance * * @example * const workStart = new TimeOnly(9, 0, 0); * const workEnd = new TimeOnly(17, 0, 0); * const currentTime = new TimeOnly(14, 30, 0); * * console.log(currentTime.isBetween(workStart, workEnd)); // true * * // Midnight-spanning range * const nightStart = new TimeOnly(22, 0, 0); * const nightEnd = new TimeOnly(6, 0, 0); * const lateNight = new TimeOnly(1, 0, 0); * * console.log(lateNight.isBetween(nightStart, nightEnd)); // true */ isBetween(start: TimeOnly, end: TimeOnly): boolean; /** * Determines whether two specified instances of TimeOnly are equal. * * @param {TimeOnly} other - The other TimeOnly to compare with * @returns {boolean} true if left and right represent the same time; otherwise, false * * @example * const time1 = new TimeOnly(14, 30, 0); * const time2 = new TimeOnly(14, 30, 0); * const time3 = new TimeOnly(14, 30, 1); * * console.log(time1.equals(time2)); // true * console.log(time1.equals(time3)); // false */ equals(other: TimeOnly): boolean; /** * Compares this instance to a specified TimeOnly value and indicates whether this instance is earlier than, the same as, or later than the specified TimeOnly value. * * @param {TimeOnly} other - The object to compare to the current instance * @returns {number} * - Less than zero if this instance is earlier than value * - Zero if this instance is the same as value * - Greater than zero if this instance is later than value * @throws {TypeError} If other is not a TimeOnly instance * * @example * const time1 = new TimeOnly(9, 0, 0); * const time2 = new TimeOnly(17, 0, 0); * * console.log(time1.compareTo(time2)); // -1 (time1 is earlier) * console.log(time2.compareTo(time1)); // 1 (time2 is later) * console.log(time1.compareTo(time1)); // 0 (same time) */ compareTo(other: TimeOnly): number; /** * Gives the elapsed time between two points on a circular clock, which will always be a positive value. * * @param {TimeOnly} other - The other TimeOnly instance * @returns {TimeSpan} The elapsed time between this and other * @throws {TypeError} If other is not a TimeOnly instance * * @example * const morning = new TimeOnly(9, 0, 0); * const evening = new TimeOnly(17, 0, 0); * * const duration = evening.subtract(morning); * console.log(duration.toString()); // "08:00:00" * * // Circular clock behavior - always positive * const reverseDuration = morning.subtract(evening); * console.log(reverseDuration.toString()); // "16:00:00" (going forward around the clock) */ subtract(other: TimeOnly): TimeSpan; /** * Converts the value of the current TimeOnly object to its equivalent string representation. * * @returns {string} A string representation of the TimeOnly in HH:mm:ss format, with fractional seconds if present * * @example * const time1 = new TimeOnly(9, 30, 0); * console.log(time1.toString()); // "09:30:00" * * const time2 = new TimeOnly(14, 15, 30, 500); * console.log(time2.toString()); // "14:15:30.5" * * const time3 = new TimeOnly(23, 59, 59, 999, 999); * console.log(time3.toString()); // "23:59:59.999999" */ toString(): string; /** * Converts the value of the current TimeOnly object to its equivalent long time string representation. * * @returns {string} A string that contains the long time string representation of the current TimeOnly object */ toLongTimeString(): string; /** * Converts the value of the current TimeOnly object to its equivalent short time string representation. * * @returns {string} A string that contains the short time string representation of the current TimeOnly object */ toShortTimeString(): string; /** * Convert the current TimeOnly instance to a TimeSpan object. * * @returns {TimeSpan} A TimeSpan object spanning to the time specified in the current TimeOnly object * * @example * const time = new TimeOnly(14, 30, 45); * const span = time.toTimeSpan(); * console.log(span.toString()); // "14:30:45" */ toTimeSpan(): TimeSpan; /** * Returns the primitive value of this TimeOnly (ticks). * * This method is called automatically when the TimeOnly is used in contexts * that require a primitive value, such as arithmetic operations or comparisons. * * @returns {number} The ticks value representing this time * * @example * const time = new TimeOnly(12, 0, 0); * console.log(+time); // Outputs the ticks value * console.log(time.valueOf()); // Same as above */ valueOf(): number; #private; } import TimeSpan from "./TimeSpan.js"; import DateTime from "./DateTime.js";