abushakir
Version:
Ethiopian Datetime and Calendar Reckoning system. COMPUTUS.
256 lines (255 loc) • 10.9 kB
JavaScript
"use strict";
// Copyright 2012 (2020 GC) Nabute. All rights reserved.
// Use of this source code is governed by MIT license, which can be found
// in the LICENSE file.
Object.defineProperty(exports, "__esModule", { value: true });
/**
* The Duration class represents an immutable span of time in microseconds.
* It provides various constructors and utility methods to manipulate and compare durations.
*/
var Duration = /** @class */ (function () {
function Duration() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (args.length === 1 && typeof args[0] === 'object' && !Array.isArray(args[0])) {
// Named parameter form
this.duration = this.computeFromNamedParams(args[0]);
}
else if (args.length === 1 && typeof args[0] === 'number') {
// Raw microseconds
this.duration = args[0];
}
else if (args.length > 1 &&
args.length <= 6 &&
args.every(function (arg) { return typeof arg === 'number' || arg === undefined || arg === null; })) {
// Positional form: [days, hours, minutes, seconds, milliseconds, microseconds]
this.duration = this.computeDuration(args);
}
else {
throw new Error('ARGUMENT ERROR: Invalid constructor usage.');
}
}
/**
* Computes the total microseconds from a list of positional arguments.
*
* @param args Array of positional arguments [days, hours, minutes, seconds, milliseconds, microseconds]
* @returns Total duration in microseconds
*/
Duration.prototype.computeDuration = function (args) {
var _a = args[0], days = _a === void 0 ? 0 : _a, _b = args[1], hours = _b === void 0 ? 0 : _b, _c = args[2], minutes = _c === void 0 ? 0 : _c, _d = args[3], seconds = _d === void 0 ? 0 : _d, _e = args[4], milliseconds = _e === void 0 ? 0 : _e, _f = args[5], microseconds = _f === void 0 ? 0 : _f;
return (Duration.MICROSECONDS_PER_DAY * this.toNumber(days) +
Duration.MICROSECONDS_PER_HOUR * this.toNumber(hours) +
Duration.MICROSECONDS_PER_MINUTE * this.toNumber(minutes) +
Duration.MICROSECONDS_PER_SECOND * this.toNumber(seconds) +
Duration.MICROSECONDS_PER_MILLISECOND * this.toNumber(milliseconds) +
this.toNumber(microseconds));
};
Duration.prototype.toNumber = function (value) {
if (value === undefined || value === null)
return 0;
if (typeof value === 'boolean')
return value ? 1 : 0;
if (typeof value === 'number')
return value;
if (typeof value === 'string') {
var parsed = parseInt(value, 10);
return isNaN(parsed) ? 0 : parsed;
}
throw new Error("Invalid input value: " + value);
};
/**
* Computes the total microseconds from a named parameters object.
*
* @param params Object with named time values
* @returns Total duration in microseconds
*/
Duration.prototype.computeFromNamedParams = function (params) {
var _a = params.days, days = _a === void 0 ? 0 : _a, _b = params.hours, hours = _b === void 0 ? 0 : _b, _c = params.minutes, minutes = _c === void 0 ? 0 : _c, _d = params.seconds, seconds = _d === void 0 ? 0 : _d, _e = params.milliseconds, milliseconds = _e === void 0 ? 0 : _e, _f = params.microseconds, microseconds = _f === void 0 ? 0 : _f;
return (days * Duration.MICROSECONDS_PER_DAY +
hours * Duration.MICROSECONDS_PER_HOUR +
minutes * Duration.MICROSECONDS_PER_MINUTE +
seconds * Duration.MICROSECONDS_PER_SECOND +
milliseconds * Duration.MICROSECONDS_PER_MILLISECOND +
microseconds);
};
Object.defineProperty(Duration.prototype, "millisecondDuration", {
/**
* Gets the raw duration value in microseconds.
*/
get: function () {
return this.duration;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Duration.prototype, "inDays", {
/** Absolute duration in days */
get: function () {
return Math.abs(this.duration / Duration.MICROSECONDS_PER_DAY);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Duration.prototype, "inHours", {
/** Absolute duration in hours */
get: function () {
return Math.abs(this.duration / Duration.MICROSECONDS_PER_HOUR);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Duration.prototype, "inMinutes", {
/** Absolute duration in minutes */
get: function () {
return Math.abs(this.duration / Duration.MICROSECONDS_PER_MINUTE);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Duration.prototype, "inSeconds", {
/** Absolute duration in seconds */
get: function () {
return Math.abs(this.duration / Duration.MICROSECONDS_PER_SECOND);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Duration.prototype, "inMilliseconds", {
/** Absolute duration in milliseconds */
get: function () {
return Math.abs(this.duration / Duration.MICROSECONDS_PER_MILLISECOND);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Duration.prototype, "inMicroseconds", {
/** Raw duration in microseconds */
get: function () {
return this.duration;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Duration.prototype, "isNegative", {
/** Indicates whether the duration is negative */
get: function () {
return this.duration < 0;
},
enumerable: true,
configurable: true
});
/** Returns the absolute value of this duration */
Duration.prototype.abs = function () {
return new Duration(Math.abs(this.duration));
};
/** Returns a new Duration that is the sum of this and another Duration */
Duration.prototype.add = function (other) {
return new Duration(this.duration + other.millisecondDuration);
};
/** Returns a new Duration that is the difference between this and another Duration */
Duration.prototype.subtract = function (other) {
return new Duration(this.duration - other.millisecondDuration);
};
/** Multiplies the duration by a numeric factor */
Duration.prototype.multiply = function (factor) {
return new Duration(Math.round(this.duration * factor));
};
/** Divides the duration by a numeric quotient */
Duration.prototype.divide = function (quotient) {
if (quotient === 0)
throw new Error('INTEGERDIVISIONBYZERO: Integer can not be divided by zero.');
return new Duration(Math.floor(this.duration / quotient));
};
/** Returns true if this Duration is greater than another */
Duration.prototype.gt = function (other) {
return this.duration > other.millisecondDuration;
};
/** Returns true if this Duration is greater than or equal to another */
Duration.prototype.gte = function (other) {
return this.duration >= other.millisecondDuration;
};
/** Returns true if this Duration is less than another */
Duration.prototype.lt = function (other) {
return this.duration < other.millisecondDuration;
};
/** Returns true if this Duration is less than or equal to another */
Duration.prototype.lte = function (other) {
return this.duration <= other.millisecondDuration;
};
/** Returns true if this Duration is equal to another */
Duration.prototype.equal = function (other) {
return this.duration === other.inMicroseconds;
};
/** Compares this Duration to another (-1, 0, 1) */
Duration.prototype.compareTo = function (other) {
if (this.lt(other))
return -1;
if (this.equal(other))
return 0;
return 1;
};
/**
* Returns a string in the format `HH:mm:ss.microseconds`
*/
Duration.prototype.toString = function () {
var totalMicro = Math.abs(this.inMicroseconds);
var totalMillis = Math.floor(totalMicro / 1000);
var hours = Math.floor(totalMillis / Duration.MILLISECONDS_PER_HOUR);
var minutes = Math.floor((totalMillis % Duration.MILLISECONDS_PER_HOUR) / Duration.MILLISECONDS_PER_MINUTE);
var seconds = Math.floor((totalMillis % Duration.MILLISECONDS_PER_MINUTE) / Duration.MILLISECONDS_PER_SECOND);
var microseconds = totalMicro % Duration.MICROSECONDS_PER_SECOND;
var sign = this.isNegative ? '-' : '';
return "" + sign + this.twoDigits(hours) + ":" + this.twoDigits(minutes) + ":" + this.twoDigits(seconds) + "." + this.sixDigits(microseconds);
};
/**
* Pads a number with leading zeros to ensure 6 digits.
*
* @param n Microseconds
*/
Duration.prototype.sixDigits = function (n) {
return n.toString().padStart(6, '0');
};
/**
* Pads a number with leading zeros to ensure 2 digits.
*
* @param n Number to format
*/
Duration.prototype.twoDigits = function (n) {
return n.toString().padStart(2, '0');
};
/** Returns the microsecond value for numeric operations */
Duration.prototype.valueOf = function () {
return this.duration;
};
/** Serializes this duration as a formatted string */
Duration.prototype.toJSON = function () {
return this.toString();
};
Object.defineProperty(Duration.prototype, Symbol.toStringTag, {
/** Overrides default [object Object] behavior */
get: function () {
return 'Duration';
},
enumerable: true,
configurable: true
});
// --- Static unit conversion factors (to prevent access-before-initialization bugs) ---
Duration.MICROSECONDS_PER_MILLISECOND = 1000;
Duration.MICROSECONDS_PER_SECOND = 1000000;
Duration.MICROSECONDS_PER_MINUTE = 60 * Duration.MICROSECONDS_PER_SECOND;
Duration.MICROSECONDS_PER_HOUR = 60 * Duration.MICROSECONDS_PER_MINUTE;
Duration.MICROSECONDS_PER_DAY = 24 * Duration.MICROSECONDS_PER_HOUR;
Duration.MILLISECONDS_PER_SECOND = 1000;
Duration.MILLISECONDS_PER_MINUTE = 60 * 1000;
Duration.MILLISECONDS_PER_HOUR = 60 * 60 * 1000;
Duration.MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
Duration.SECONDS_PER_MINUTE = 60;
Duration.SECONDS_PER_HOUR = 60 * 60;
Duration.SECONDS_PER_DAY = 24 * 60 * 60;
Duration.MINUTES_PER_HOUR = 60;
Duration.MINUTES_PER_DAY = 24 * 60;
return Duration;
}());
exports.default = Duration;