Skip to content

Commit

Permalink
Merge pull request #14 from retraigo/dev
Browse files Browse the repository at this point in the history
TS rewrite
  • Loading branch information
retraigo authored Mar 29, 2022
2 parents 8b2cbaa + ab7863b commit 0241d9e
Show file tree
Hide file tree
Showing 8 changed files with 542 additions and 295 deletions.
4 changes: 4 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.vscode
dumpster.js
.pnpm-debug.log
mod.ts
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"deno.enable": true
}
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ $ pnpm install @retraigo/duration.js # PNPM
// Node
import Duration from "@retraigo/duration.js";
// Deno
import Duration from "https://deno.land/x/durationjs@v2.1.3/index.js";
import Duration from "https://deno.land/x/durationjs@v2.3.2/mod.ts";

const Duration = await import("@retraigo/duration.js"); // Node with CommonJS

Expand Down Expand Up @@ -57,6 +57,8 @@ Duration {
m: 0, // Minutes
s: 0, // Seconds
ms: 0 // Milliseconds
us: 0 // Microseconds
ns: 0 // Nanoseconds
};
```

Expand Down
288 changes: 2 additions & 286 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,286 +1,2 @@
/**
* A simple JavaScript class used to parse time durations
* @module Duration
*/

const keyList = {
d: "days",
h: "hours",
m: "minutes",
s: "seconds",
ms: "milliseconds",
ns: "nanoseconds",
us: "microseconds",
};

/**
* For the array of values
* @typedef {object} KeyValue
* @property {string} type - Type of key. One of d, h, m, s, ms
* @property {number} value - Value of the time unit
*/

/**
* Duration Object
* @typedef {Object} DurationObj
* @property {Number} raw - Total number of milliseconds in the duration
* @property {Number} d - Number of days held by duration
* @property {Number} h - Number of hours held by duration
* @property {Number} m - Number of minutes held by duration
* @property {Number} s - Number of seconds held by duration
* @property {Number} ms - Number of milliseconds held by duration
* @property {Number} us - Number of microseconds held by duration
* @property {Number} ns - Number of nanoseconds held by duration
*/

/**
* A duration class which parses milliseconds into human readable form.
* @class
*/

class Duration {
/**
* Create a new Duration
* @param {number} timestamp - Duration in milliseconds
* @returns {<Duration>}
*/
constructor(timestamp = Duration.getCurrentDuration()) {
if (timestamp < 0) timestamp = 0; // Prevent negative time
this.raw = timestamp;
this.d = Math.trunc(timestamp / 86400000);
this.h = Math.trunc(timestamp / 3600000) % 24;
this.m = Math.trunc(timestamp / 60000) % 60;
this.s = Math.trunc(timestamp / 1000) % 60;
this.ms = Math.trunc(timestamp) % 1000;
this.us = Math.trunc(timestamp * 1000) % 1000;
this.ns = Math.trunc(timestamp * 1000000) % 1000;
}
/**
* Data in the class mapped into an Array with properties "type" and "value"
* @returns {KeyValue[]}
*/
get array() {
return [
{ type: "d", value: this.d },
{ type: "h", value: this.h },
{ type: "m", value: this.m },
{ type: "s", value: this.s },
{ type: "ms", value: this.ms },
{ type: "ns", value: this.ns },
{ type: "us", value: this.µs },
];
}
/**
* Alt way to get microseconds
*/
get µs() {
return this.us;
}
/**
* Data in the class mapped as a JavaScript Object.
* @returns {DurationObj}
*/
get json() {
return this.array.reduce(
(acc, stuff) => ((acc[stuff.type] = stuff.value), acc),
{},
);
}
/**
* @param {string[]} values - The values required to display
* @param {boolean} shortandsweet - If response should be a short string.
* @returns {string} formatted string - The formatted string result
*/
stringify(values = [], shortandsweet = false) {
if (!Array.isArray(values) || values.length == 0) {
if (
!shortandsweet ||
typeof shortandsweet !== "boolean" ||
shortandsweet == false
) {
return `${
this.array
.map((x) => `${x.value} ${keyList[x.type]}`)
.join(", ")
}`;
}
return `${this.array.map((x) => `${x.value}${x.type}`).join(" ")}`;
}
if (values.length > 0) {
if (
!shortandsweet ||
typeof shortandsweet !== "boolean" ||
shortandsweet == false
) {
return `${
this.array
.filter((x) => values.includes(x.type))
.map((x) => `${x.value} ${keyList[x.type]}`)
.join(", ")
}`;
}
return `${
this.array
.filter((x) => values.includes(x.type))
.map((x) => `${x.value}${x.type}`)
.join(" ")
}`;
}
return `${
this.array
.map((x) => `${x.value} ${keyList[x.type]}`)
.join(", ")
}`;
}
/**
* Get a duration formatted using colons (:)
* @param {string} fromT - Unit to display from
* @param {string} toT - Unit to display upto
* @returns {string} Formatted string
*/
getFormattedDuration(fromT = "d", toT = "µs") {
if (
typeof fromT !== "string" ||
typeof toT !== "string" ||
!keyList.hasOwnProperty(fromT.toLowerCase()) ||
!keyList.hasOwnProperty(toT.toLowerCase())
) {
return this.getSimpleFormattedDuration();
}
const durations = [];
const next =
this.array[this.array.findIndex((x) => x.type === toT.toLowerCase()) + 1];
for (const obj of this.array) {
if (obj.type !== fromT.toLowerCase() && durations.length === 0) continue;
if (obj.type === next.type) break;
durations.push(obj.value);
}
return durations.join(":");
}
/**
* Get a simple formatted duration in the form dd:hh:mm:ss:ms
* @returns {string} Formatted string
*/
getSimpleFormattedDuration() {
return `${this.array.map((x) => x.value).join(":")}`;
}
/**
* Extra filler function that returns the class data in a single short string.
* @returns {string} Dumb string
*/
toString() {
return `[Duration ${this.stringify(["d", "h", "m", "s"], true)}]`;
}
/**
* Updated data to match any modification to values.
* @returns {<Duration>}
*/
reload() {
const ts = this.d * 8.64e7 +
this.h * 3600000 +
this.m * 60000 +
this.s * 1000 +
this.ms + (this.us / 1000) + (this.ns / 1000000);
if (ts === this.raw) return this;
const newDuration = new Duration(ts);
this.d = newDuration.d;
this.h = newDuration.h;
this.m = newDuration.m;
this.s = newDuration.s;
this.ms = newDuration.ms;
this.ns = newDuration.ns;
this.us = newDuration.us;
this.raw = newDuration.raw;
return this;
}
/**
* Reads a given string and parses a duration from it.
* @param {string} str - A string which could contain a duration
* @param {string} doNotParse - Directly return the values read
* @returns {<Duration>}
*/
static fromString(str, doNotParse = false) {
const { d, h, m, s, ms, ns, us } = Duration.readString(str);
const ts = d * 8.64e7 + h * 3600000 + m * 60000 + s * 1000 + ms +
(us / 1000) +
(ns / 1000000);

const newDuration = new Duration(ts);
if (doNotParse) {
newDuration.d = d;
newDuration.h = h;
newDuration.m = m;
newDuration.s = s;
newDuration.ms = ms;
newDuration.ns = ns;
newDuration.us = us;
}
return newDuration;
}
/**
* Get the duration till next midnight in milliseconds.
* @returns {number} Duration in milliseconds till the next midnight
*/
static getCurrentDuration() {
return new Date().setHours(0, 0, 0, 0);
}
/**
* Read duration data from a string.
* @param {string} str - The string to read
* @returns {DurationObj} obj - Object with days, hours, mins, seconds and milliseconds
*/
static readString(str) {
str = str.replace(/\s\s/g, "");
const days = matchReg(str, "d") || matchReg(str, "days") ||
matchReg(str, "day");
const hours = matchReg(str, "h") || matchReg(str, "hours") ||
matchReg(str, "hour");
const minutes = matchReg(str, "m") ||
matchReg(str, "min") ||
matchReg(str, "minute") ||
matchReg(str, "mins") ||
matchReg(str, "minutes");
const seconds = matchReg(str, "s") ||
matchReg(str, "sec") ||
matchReg(str, "second") ||
matchReg(str, "secs") ||
matchReg(str, "seconds");
const milliseconds = matchReg(str, "ms") ||
matchReg(str, "millisecond") ||
matchReg(str, "milliseconds");
const nanoseconds = matchReg(str, "ns") ||
matchReg(str, "nanosecond") ||
matchReg(str, "nanoseconds");
const microseconds = matchReg(str, "µs") ||
matchReg(str, "microsecond") ||
matchReg(str, "microseconds");
matchReg(str, "us");
return {
d: days,
h: hours,
m: minutes,
s: seconds,
ms: milliseconds,
ns: nanoseconds,
us: microseconds,
};
}
}

/**
* Match a unit in a string. Like "1kg", "3L", etc.
* @param {string} str - String to match from
* @param {string} t - Unit to look for. Doesn't support aliases.
* @returns {number} value - Value of the unit matched
*/
function matchReg(str, t) {
const reg = new RegExp(`(\\d+)\\s?${t}(?:[^a-z]|$)`, "i");
const matched = reg.exec(str);
if (!matched) return 0;
return parseInt(matched[1].replace(t, ""));
}

// module.exports = Duration;

export default Duration;
export { Duration, matchReg as MatchUnit };
// Will be removed at the next major version bump
export * from "./mod.js"
Loading

0 comments on commit 0241d9e

Please sign in to comment.