@softwareventures/time
Version:
Data types and functions for working with abstract times of day
351 lines (350 loc) • 15.8 kB
TypeScript
/** @file Data types and functions for working with abstract times of day. */
import * as format from "@softwareventures/format-time";
import type { Comparator } from "@softwareventures/ordered";
import { Comparison } from "@softwareventures/ordered";
/** An abstract time of day with no associated timezone or date. */
export interface Time {
/** Type discriminator identifying the object as a `Time`. */
readonly type: "Time";
/** The hours component of the time of day. Should be an integer in the
* range `0`-`23`. */
readonly hours: number;
/** The minutes component of the time of day. Should be an integer in the
* range `0`-`59`. */
readonly minutes: number;
/** The seconds component of the time of day. Should be in the range
* `0`-`60`, inclusive of `0` but exclusive of `60`. May be fractional
* to represent an instant in time with sub-second accuracy. */
readonly seconds: number;
}
/** Options for creating a {@link Time}.
*
* An instance of {@link Time} may always be used in place of `TimeOptions`. */
export type TimeOptions = Partial<Time>;
/** Returns `true` if the specified value has the shape of a `Time` object.
*
* The `hours`, `minutes` and `seconds` fields may be non-integers or outside
* the expected range, meaning that the object may not represent a valid time.
*
* To test if the object represents a valid time, call {@link isValid} or
* {@link isValidTime}. */
export declare function isTime(value: unknown): value is Time;
/** Tests if the specified value is a {@link Time} object representing a valid
* time.
*
* Returns `true` if the value has the shape of a `Time` object, the `hours` and
* `minutes` fields are integers within the expected range, and `seconds`
* is a number within the expected range. */
export declare function isValidTime(value: unknown): value is Time;
/** Tests if the specified {@link Time} object represents a valid time.
*
* Returns true if `hours` and `minutes` are integers within the expected
* range, and `seconds` is a number within the expected range.
*
* Times returned by functions in this library are always valid. */
export declare function isValid(time: Time): boolean;
/** Tests if the specified {@link Time} object represents a valid time.
*
* Returns true if `hours` and `minutes` are integers within the expected
* range, and `seconds` is a number within the expected range.
*
* Times returned by functions in this library are always valid. */
export declare const isTimeValid: typeof isValid;
/**
* Asserts that the specified {@link Time} object represents a valid time.
*
* Times returned by functions in this library are always valid.
*
* @throws {Error} if any of the `hour` or `minute` fields are non-integers,
* or if any of the `hour`, `minute` or `second` fields are outside the
* valid range.
*/
export declare function validate(time: Time): void;
/**
* Asserts that the specified {@link Time} object represents a valid time.
*
* Times returned by functions in this library are always valid.
*
* Alias of {@link validate}, useful for disambiguation from similar functions
* that operate on other types.
*
* @throws {Error} if any of the `hour` or `minute` fields are non-integers,
* or if any of the `hour`, `minute` or `second` fields are outside the
* valid range.
*/
export declare const validateTime: typeof validate;
/** Creates a {@link Time} with the specified options.
*
* If any numeric components are unspecified, they default to zero.
*
* If any numeric components are outside the expected range, then they
* will roll over into the next larger component. If the time as a whole
* is outside the 24-hour range, then the time will wrap around by as
* many 24-hour periods as needed to put it in the valid range.
*
* @throws {Error} if any of the numeric components are non-finite. */
export declare function time(time: TimeOptions): Time;
/** Normalizes the specified {@link Time} object so that it represents a valid
* time.
*
* If any numeric components are unspecified, they default to zero.
*
* If any numeric components are outside the expected range, then they
* will roll over into the next larger component. If the time as a whole
* is outside the 24-hour range, then the time will wrap around by as
* many 24-hour periods as needed to put it in the valid range.
*
* Alias of {@link time}. Calling the function by this name instead might make
* code clearer in cases where the purpose is to normalize an existing `Time`
* object.
*
* @throws {Error} if any of the numeric components are non-finite. */
export declare const normalize: typeof time;
/** Normalizes the specified {@link Time} object so that it represents a valid
* time.
*
* If any numeric components are unspecified, they default to zero.
*
* If any numeric components are outside the expected range, then they
* will roll over into the next larger component. If the time as a whole
* is outside the 24-hour range, then the time will wrap around by as
* many 24-hour periods as needed to put it in the valid range.
*
* Alias of {@link time}. Calling the function by this name instead might make
* code clearer in cases where the purpose is to normalize an existing `Time`
* object.
*
* @throws {Error} if any of the numeric components are non-finite. */
export declare const normalizeTime: typeof time;
/** Converts the specified {@link Time} to a count of seconds since
* midnight. */
export declare function toReferenceSeconds(time: TimeOptions): number;
/** Converts the specified {@link Time} to a count of seconds since
* midnight.
*
* Alias of {@link toReferenceSeconds}, useful for disambiguation from similar
* functions that operate on other types. */
export declare const timeToReferenceSeconds: typeof toReferenceSeconds;
/** Creates a {@link Time} corresponding to the specified count of seconds
* since midnight.
*
* @throws {Error} if seconds is not a finite value. */
export declare function fromReferenceSeconds(seconds: number): Time;
/** Creates a {@link Time} corresponding to the specified count of seconds
* since midnight.
*
* Alias of {@link fromReferenceSeconds}, useful for disambiguation from
* similar functions that operate on other types.
*
* @throws {Error} if seconds is not a finite value. */
export declare const timeFromReferenceSeconds: typeof fromReferenceSeconds;
/** Tests if two {@link Time}s are equal. */
export declare function equal(a: TimeOptions, b: TimeOptions): boolean;
/** Tests if two {@link Time}s are equal.
*
* Alias of {@link equal}, useful for disambiguation from other equality
* functions. */
export declare const timeEqual: typeof equal;
/** Tests if two {@link Time}s are equal.
*
* Curried variant of {@link equal}. */
export declare function equalFn(b: TimeOptions): (a: TimeOptions) => boolean;
/** Tests if two {@link Time}s are equal.
*
* Curried variant of {@link timeEqual}. */
export declare const timeEqualFn: typeof equalFn;
/** Tests if two {@link Time}s are not equal. */
export declare function notEqual(a: TimeOptions, b: TimeOptions): boolean;
/** Tests if two {@link Time}s are not equal.
*
* Alias of {@link notEqual}, useful for disambiguation from other inequality
* functions. */
export declare const timeNotEqual: typeof notEqual;
/** Tests if two {@link Time}s are not equal.
*
* Curried variant of {@link notEqual}. */
export declare function notEqualFn(b: TimeOptions): (a: TimeOptions) => boolean;
/** Tests if two {@link Time}s are not equal.
*
* Curried variant of {@link timeNotEqual}. */
export declare const timeNotEqualFn: typeof notEqualFn;
/** Compares two {@link Time}s.
*
* Time `a` is considered to be `before` time `b` if time `a` is
* earlier in the day. */
export declare const compare: Comparator<TimeOptions>;
/** Compares two {@link Time}s.
*
* Time `a` is considered to be `before` time `b` if time `a` is
* earlier in the day.
*
* Alias of {@link compare}, useful for disambiguation from other comparison
* functions. */
export declare const timeCompare: Comparator<Partial<Time>>;
/** Compares two {@link Time}s.
*
* Time `a` is considered to be `before` time `b` if time `a` is
* earlier in the day.
*
* Curried variant of {@link compare}. */
export declare function compareFn(b: TimeOptions): (a: TimeOptions) => Comparison;
/** Compares two {@link Time}s.
*
* Time `a` is considered to be `before` time `b` if time `a` is
* earlier in the day.
*
* Curried variant of {@link timeCompare}. */
export declare const timeCompareFn: typeof compareFn;
/** Tests if {@link Time} `a` is earlier in the day than {@link Time} `b`. */
export declare function before(a: TimeOptions, b: TimeOptions): boolean;
/** Tests if {@link Time} `a` is earlier in the day than {@link Time} `b`.
*
* Alias of {@link before}, useful for disambiguation from similar functions
* that operate on other date/time types. */
export declare const timeBefore: typeof before;
/** Tests if {@link Time} `a` is earlier in the day than {@link Time} `b`.
*
* Curried variant of {@link before}. */
export declare function beforeFn(b: TimeOptions): (a: TimeOptions) => boolean;
/** Tests if {@link Time} `a` is earlier in the day than {@link Time} `b`.
*
* Curried variant of {@link timeBefore}. */
export declare const timeBeforeFn: typeof beforeFn;
/** Tests if {@link Time} `a` is equal to or earlier in the day than
* {@link Time} `b`. */
export declare function beforeOrEqual(a: TimeOptions, b: TimeOptions): boolean;
/** Tests if {@link Time} `a` is equal to or earlier in the day than
* {@link Time} `b`.
*
* Alias of {@link beforeOrEqual}, useful for disambiguation from similar
* functions that operate on other date/time types. */
export declare const timeBeforeOrEqual: typeof beforeOrEqual;
/** Tests if {@link Time} `a` is equal to or earlier in the day than
* {@link Time} `b`.
*
* Curried variant of {@link beforeOrEqual}. */
export declare function beforeOrEqualFn(b: TimeOptions): (a: TimeOptions) => boolean;
/** Tests if {@link Time} `a` is equal to or earlier in the day than
* {@link Time} `b`.
*
* Curried variant of {@link timeBeforeOrEqual}. */
export declare const timeBeforeOrEqualFn: typeof beforeOrEqualFn;
/** Tests if {@link Time} `a` is later in the day than {@link Time} `b`. */
export declare function after(a: TimeOptions, b: TimeOptions): boolean;
/** Tests if {@link Time} `a` is later in the day than {@link Time} `b`.
*
* Alias of {@link after}, useful for disambiguation from similar functions
* that operate on other date/time types. */
export declare const timeAfter: typeof after;
/** Tests if {@link Time} `a` is later in the day than {@link Time} `b`.
*
* Curried variant of {@link after}. */
export declare function afterFn(b: TimeOptions): (a: TimeOptions) => boolean;
/** Tests if {@link Time} `a` is later in the day than {@link Time} `b`.
*
* Curried variant of {@link timeAfter}. */
export declare const timeAfterFn: typeof afterFn;
/** Returns the current time of day according to UTC. */
export declare function nowUtc(): Time;
/** Returns the current time of day according to UTC.
*
* Alias of {@link nowUtc}, useful for disambiguation from similar functions
* that operate on other date/time types. */
export declare const timeNowUtc: typeof nowUtc;
/** Returns the current time of day according to the device's local
* timezone. */
export declare function nowDeviceLocal(): Time;
/** Returns the current time of day according to the device's local timezone.
*
* Alias of {@link nowDeviceLocal}, useful for disambiguation from similar
* functions that operate on other date/time types. */
export declare const timeNowDeviceLocal: typeof nowDeviceLocal;
/**
* Parses a {@link Time} from text in ISO 8601 format.
*
* The ISO 8601 text must not specify a time zone offset.
*
* If the specified text is not a valid ISO 8601 time then this function
* returns `null`.
*
* Both extended `Thh:mm:ss.sss` and basic `Thhmmss.sss` ISO 8601 formats are
* accepted, and the initial `T` is optional in both cases. The seconds field
* may be omitted, and the minutes field may also be omitted if the seconds
* field is omitted. Omitted fields default to zero.
*/
export declare function parseIso8601(text: string): Time | null;
/**
* Parses a {@link Time} from text in ISO 8601 format.
*
* The ISO 8601 text must not specify a time zone offset.
*
* If the specified text is not a valid ISO 8601 time then this function
* returns `null`.
*
* Both extended `Thh:mm:ss.sss` and basic `Thhmmss.sss` ISO 8601 formats are
* accepted, and the initial `T` is optional in both cases. The seconds field
* may be omitted, and the minutes field may also be omitted if the seconds
* field is omitted. Omitted fields default to zero.
*
* Alias of {@link parseIso8601}, useful for disambiguation from similar
* functions that operate on other date/time types. */
export declare const parseTimeIso8601: typeof parseIso8601;
export type { Iso8601Options, TimeFormatter } from "@softwareventures/format-time";
/** Returns a {@link TimeFormatter} that formats the specified {@link Time} as
* ISO 8601, with the specified options.
*
* By default, the {@link Time} is formatted in the "extended" ISO 8601 format,
* with the leading `"T"`, and without rounding, for example
* `"T11:57:23.723615"`.
*
* If the `format` option is set to `"basic"`, then the colons are omitted,
* for example `"T115723.723615"`.
*
* If the `round` option is set to `"seconds"`, then the time is rounded down
* to the next lower second, for example `"T11:57:23"`.
*
* If the `round` option is set to `"ms"`, then the time is rounded down to
* the next lower millisecond, for example `"T11:57:23.723"`.
*
* If the `leadingT` option is set to `false`, then the leading `"T"` is
* omitted, for example `"11:57:23.363215"`.
*
* For other formats, see `@softwareventures/format-time`. */
export declare const formatIso8601: typeof format.iso8601;
/** Returns a {@link TimeFormatter} that formats the specified {@link Time} as
* ISO 8601, with the specified options.
*
* By default, the {@link Time} is formatted in the "extended" ISO 8601 format,
* with the leading `"T"`, and without rounding, for example
* `"T11:57:23.723615"`.
*
* If the `format` option is set to `"basic"`, then the colons are omitted,
* for example `"T115723.723615"`.
*
* If the `round` option is set to `"seconds"`, then the time is rounded down
* to the next lower second, for example `"T11:57:23"`.
*
* If the `round` option is set to `"ms"`, then the time is rounded down to
* the next lower millisecond, for example `"T11:57:23.723"`.
*
* If the `leadingT` option is set to `false`, then the leading `"T"` is
* omitted, for example `"11:57:23.363215"`.
*
* Alias of {@link formatIso8601}, useful for disambiguation from similar
* functions that operate on other date/time types.
*
* For other formats, see `@softwareventures/format-time`. */
export declare const formatTimeIso8601: typeof format.iso8601;
/** Formats the specified {@link Time} as ISO 8601 extended, rounded down to
* the next lower second, and with no leading `"T"`.
*
* This format is intended to be reasonable for display to humans. */
export declare const formatHumanIso8601: format.TimeFormatter;
/** Formats the specified {@link Time} as ISO 8601 extended, rounded down to
* the next lower second, and with no leading `"T"`.
*
* This format is intended to be reasonable for display to humans.
*
* Alias of {@link formatHumanIso8601}, useful for disambiguation from similar
* functions that operate on other date/time types. */
export declare const formatTimeHumanIso8601: format.TimeFormatter;