/**
* Represents a network timestamp.
*/
export class NetworkTimestamp {
/**
* Creates a timestamp.
* @param {number|bigint} timestamp Raw network timestamp.
*/
constructor(timestamp) {
/**
* Underlying timestamp.
* @type bigint
*/
this.timestamp = BigInt(timestamp);
}
/**
* Determines if this is the epochal timestamp.
*/
get isEpochal() {
return 0n === this.timestamp;
}
/**
* Adds a specified number of seconds to this timestamp.
* @abstract
* @param {number|bigint} count Number of seconds to add.
* @returns {NetworkTimestamp} New timestamp that is the specified number of seconds past this timestamp.
*/
addSeconds(count) { // eslint-disable-line class-methods-use-this, no-unused-vars
throw new Error('`addSeconds` must be implemented by concrete class');
}
/**
* Adds a specified number of minutes to this timestamp.
* @param {number|bigint} count Number of minutes to add.
* @returns {NetworkTimestamp} New timestamp that is the specified number of minutes past this timestamp.
*/
addMinutes(count) {
return this.addSeconds(60n * BigInt(count));
}
/**
* Adds a specified number of hours to this timestamp.
* @param {number|bigint} count Number of hours to add.
* @returns {NetworkTimestamp} New timestamp that is the specified number of hours past this timestamp.
*/
addHours(count) {
return this.addMinutes(60n * BigInt(count));
}
/**
* Returns string representation of this object.
* @returns {string} String representation of this object
*/
toString() {
return this.timestamp.toString();
}
}
/**
* Provides utilities for converting between network timestamps and datetimes.
*/
export class NetworkTimestampDatetimeConverter {
/**
* Creates a converter given an epoch and base time units.
* @param {Date} epoch Date at which network started.
* @param {string} timeUnits Time unit the network uses for progressing.
*/
constructor(epoch, timeUnits) {
/**
* Date at which network started
* @type Date
*/
this.epoch = epoch;
/**
* Number of milliseconds per time unit.
* @type number
*/
this.timeUnits = {
hours: 60 * 60 * 1000,
minutes: 60 * 1000,
seconds: 1000,
milliseconds: 1
}[timeUnits];
}
/**
* Converts a network timestamp to a datetime.
* @param {number} rawTimestamp Raw network timestamp.
* @returns {Date} Date representation of the network timestamp.
*/
toDatetime(rawTimestamp) {
return new Date(this.epoch.getTime() + (Number(rawTimestamp) * this.timeUnits));
}
/**
* Subtracts the network epoch from the reference date.
* @param {Date} referenceDatetime Reference date.
* @returns {number} Number of network time units between the reference date and the network epoch.
*/
toDifference(referenceDatetime) {
if (referenceDatetime < this.epoch)
throw RangeError('timestamp cannot be before epoch');
const subtractDates = (lhs, rhs) => (lhs - rhs);
return subtractDates(referenceDatetime, this.epoch) / this.timeUnits;
}
}