UNPKG

@datastax/astra-db-ts

Version:
233 lines (232 loc) 9.61 kB
"use strict"; // Copyright Datastax, Inc // SPDX-License-Identifier: Apache-2.0 Object.defineProperty(exports, "__esModule", { value: true }); exports.time = exports.DataAPITime = void 0; const constants_js_1 = require("../../lib/constants.js"); const constants_js_2 = require("../../documents/collections/ser-des/constants.js"); const constants_js_3 = require("../../documents/tables/ser-des/constants.js"); const utils_js_1 = require("../../documents/utils.js"); const utils_js_2 = require("../../lib/api/ser-des/utils.js"); class DataAPITime { [constants_js_2.$SerializeForCollection]() { throw (0, utils_js_2.mkTypeUnsupportedForCollectionsError)('DataAPITime', '_time', [ 'Use a native Javascript Date object', 'Use another time representation, such as a string, or an object containing the hours, minutes, seconds, and nanoseconds', ]); } ; [constants_js_3.$SerializeForTable](ctx) { return ctx.done(this.toString()); } ; static [constants_js_3.$DeserializeForTable](value, ctx) { return ctx.done(new DataAPITime(value)); } static now() { return new DataAPITime(new Date()); } static utcnow() { return new DataAPITime(...ofNanoOfDay((Date.now() % 86400000) * 1000000)); } static ofNanoOfDay(nanoOfDay) { return new DataAPITime(...ofNanoOfDay(nanoOfDay)); } static ofSecondOfDay(secondOfDay) { return new DataAPITime(...ofSecondOfDay(secondOfDay)); } constructor(i1, i2, i3, i4) { Object.defineProperty(this, "hours", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "minutes", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "seconds", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "nanoseconds", { enumerable: true, configurable: true, writable: true, value: void 0 }); switch (arguments.length) { case 1: { if (typeof i1 === 'string') { [this.hours, this.minutes, this.seconds, this.nanoseconds] = parseTimeStr(i1, true); } else if (i1 instanceof Date) { if (isNaN(i1.getTime())) { throw new Error(`Invalid date '${i1.toString()}'; must be a valid (non-NaN) date`); } this.hours = i1.getHours(); this.minutes = i1.getMinutes(); this.seconds = i1.getSeconds(); this.nanoseconds = i1.getMilliseconds() * 1000000; } else { throw (0, utils_js_1.mkInvArgsError)('new DataAPITime', [['time', 'string | Date']], i1); } break; } case 2: case 3: case 4: { if (typeof i1 === 'string') { [this.hours, this.minutes, this.seconds, this.nanoseconds] = parseTimeStr(i1, i2 !== false); } else if (typeof i1 === 'number' && typeof i2 === 'number' && (!i3 || typeof i3 === 'number') && (!i4 || typeof i4 === 'number')) { this.hours = i1; this.minutes = i2; this.seconds = i3 || 0; this.nanoseconds = i4 || 0; validateTime(this.hours, this.minutes, this.seconds, this.nanoseconds); } else { throw (0, utils_js_1.mkInvArgsError)('new DataAPIDate', [['hour', 'number'], ['minute', 'number'], ['second', 'number?'], ['nanosecond', 'number?']], i1, i2, i3, i4); } break; } default: { throw RangeError(`Invalid number of arguments; expected 1..=4, got ${arguments.length}`); } } Object.defineProperty(this, constants_js_1.$CustomInspect, { value: () => `DataAPITime("${this.toString()}")`, }); } toDate(base) { base || (base = new Date()); if (base instanceof Date) { return new Date(base.getFullYear(), base.getMonth(), base.getDate(), this.hours, this.minutes, this.seconds, this.nanoseconds / 1000000); } return new Date(base.year, base.month - 1, base.date, this.hours, this.minutes, this.seconds, this.nanoseconds / 1000000); } toDateUTC(base) { base || (base = new Date()); if (base instanceof Date) { return new Date(Date.UTC(base.getUTCFullYear(), base.getUTCMonth(), base.getUTCDate(), this.hours, this.minutes, this.seconds, this.nanoseconds / 1000000)); } return new Date(Date.UTC(base.year, base.month - 1, base.date, this.hours, this.minutes, this.seconds, this.nanoseconds / 1000000)); } toString() { return `${this.hours.toString().padStart(2, '0')}:${this.minutes.toString().padStart(2, '0')}:${this.seconds.toString().padStart(2, '0')}.${this.nanoseconds.toString().padStart(9, '0')}`; } compare(other) { if (this.hours !== other.hours) { return this.hours < other.hours ? -1 : 1; } if (this.minutes !== other.minutes) { return this.minutes < other.minutes ? -1 : 1; } if (this.seconds !== other.seconds) { return this.seconds < other.seconds ? -1 : 1; } if (this.nanoseconds !== other.nanoseconds) { return this.nanoseconds < other.nanoseconds ? -1 : 1; } return 0; } equals(other) { return (other instanceof DataAPITime) && this.compare(other) === 0; } } exports.DataAPITime = DataAPITime; exports.time = Object.assign((...params) => (params[0] instanceof DataAPITime) ? params[0] : new DataAPITime(...params), { now: DataAPITime.now, utcnow: DataAPITime.utcnow, ofNanoOfDay: DataAPITime.ofNanoOfDay, ofSecondOfDay: DataAPITime.ofSecondOfDay, }); const parseTimeStr = (str, strict) => { return (strict) ? parseTimeStrict(str) : parseTimeQuick(str); }; const parseTimeQuick = (str) => { const hour = parseInt(str.slice(0, 2), 10); const minute = parseInt(str.slice(3, 5), 10); const second = (str.length > 5) ? parseInt(str.slice(6, 8), 10) : 0; const nanoseconds = (str.length > 9) ? parseInt(str.slice(9), 10) * Math.pow(10, 9 - (str.length - 9)) : 0; return [hour, minute, second, nanoseconds]; }; const TimeRegex = /^(\d\d):(\d\d)(?::(\d\d(?:\.(\d{0,9}))?))?$/; const parseTimeStrict = (str) => { const match = TimeRegex.exec(str); if (!match) { throw Error(`Invalid time: '${str}'; must match HH:MM[:SS[.NNNNNNNNN]]`); } const time = [ parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3] || '0', 10), parseInt(match[4] || '0', 10) * Math.pow(10, 9 - (match[4]?.length ?? 0)), ]; validateTime(...time); return time; }; const validateTime = (hours, minutes, seconds, nanoseconds) => { if (!Number.isInteger(hours) || !Number.isInteger(minutes) || !Number.isInteger(seconds) || !Number.isInteger(nanoseconds)) { throw new TypeError(`Invalid hour: ${hours}, minute: ${minutes}, second: ${seconds}, and/or nanosecond: ${nanoseconds}; must be integers`); } if (hours < 0 || hours > 23) { throw RangeError(`Invalid hour: ${hours}; must be in range [0, 23]`); } if (minutes < 0 || minutes > 59) { throw RangeError(`Invalid minute: ${minutes}; must be in range [0, 59]`); } if (seconds < 0 || seconds > 59) { throw RangeError(`Invalid second: ${seconds}; must be in range [0, 59]`); } if (nanoseconds < 0 || nanoseconds > 999999999) { throw RangeError(`Invalid nanosecond: ${nanoseconds}; must be in range [0, 999,999,999]`); } }; const ofSecondOfDay = (s) => { if (typeof s !== 'number') { throw (0, utils_js_1.mkInvArgsError)('DataAPITime.ofSecondOfDay', [['secondOfDay', 'number']], s); } if (!Number.isInteger(s)) { throw new TypeError(`Invalid number of seconds: ${s}; must be an integer`); } if (s < 0 || 86399 < s) { throw RangeError(`Invalid number of seconds: ${s}; must be in range [0, 86,399]`); } const hours = ~~(s / 3600); s -= hours * 3600; const minutes = ~~(s / 60); s -= minutes * 60; return [hours, minutes, s, 0]; }; const ofNanoOfDay = (ns) => { if (typeof ns !== 'number') { throw (0, utils_js_1.mkInvArgsError)('DataAPITime.ofNanoOfDay', [['nanoOfDay', 'number']], ns); } if (!Number.isInteger(ns)) { throw new TypeError(`Invalid number of nanoseconds: ${ns}; must be an integer`); } if (ns < 0 || 86399999999999 < ns) { throw RangeError(`Invalid number of nanoseconds: ${ns}; must be in range [0, 86,399,999,999,999]`); } const hours = ~~(ns / 3600000000000); ns -= hours * 3600000000000; const minutes = ~~(ns / 60000000000); ns -= minutes * 60000000000; const seconds = ~~(ns / 1000000000); ns -= seconds * 1000000000; return [hours, minutes, seconds, ns]; };