diff --git a/modules/time_utils.js b/modules/time_utils.js index 152de2fd0..5ca153710 100644 --- a/modules/time_utils.js +++ b/modules/time_utils.js @@ -1,54 +1,78 @@ // module "time_utils" // // Utility functions useful to work with time and durations. -// Functions usually receive or return a {h, m} object or a -// number of milliseconds representing a time or a duration. +// +// This module functions usually receive or return a {d, h, m, s} object +// or a number of milliseconds representing a time or a duration. +// +// The {h, m, s} object encapsulates a "time" (eg: 12:30:00). +// Note: a "time" needs the day set to 0/undefined, otherwise it is a "duration". +// +// The {d, h, m, s} object encapsulates a "duration" in number of days, hours, +// minutes and seconds (eg. 3d 20h 35m 20s). +// Note that if a field is undefined then its value is zero. // +const ONE_SECOND = 1000; +const ONE_MINUTE = 60 * ONE_SECOND; +const ONE_HOUR = 60 * ONE_MINUTE; +const ONE_DAY = 24 * ONE_HOUR; + /** - * @param {object} time {h, m} + * @param {object} time {d, h, m, s} * @returns the milliseconds contained in the passed time object */ -exports.encodeTime = (time) => time.h * 3600000 + time.m * 60000; +exports.encodeTime = (time) => { + time = safeTime(time); + return time.d * ONE_DAY + time.h * ONE_HOUR + time.m * ONE_MINUTE + time.s * ONE_SECOND; +} + +// internal use, set to zero all the undefined fields +function safeTime(time) { + return { d: time.d || 0, h: time.h || 0, m: time.m || 0, s: time.s || 0 }; +} /** * @param {int} millis the number of milliseconds - * @returns a time object {h, m} built from the milliseconds + * @returns a time object {d, h, m, s} built from the milliseconds */ exports.decodeTime = (millis) => { - millis = Math.ceil(millis / 60000); - var h = 0 | (millis / 60); - return { - h: h, - m: millis - h * 60 - }; + if (typeof millis !== "number") throw "Only a number can be decoded"; + var d = Math.floor(millis / ONE_DAY); + millis -= d * ONE_DAY; + var h = Math.floor(millis / ONE_HOUR); + millis -= h * ONE_HOUR; + var m = Math.floor(millis / ONE_MINUTE); + millis -= m * ONE_MINUTE; + var s = Math.floor(millis / ONE_SECOND); + return { d: d, h: h, m: m, s: s }; } /** - * @param {object|int} value {h,m} object or milliseconds + * @param {object|int} value {h, m} object or milliseconds * @returns an human-readable time string like "10:25" + * @throws an exception if d != 0 or h > 23 or m > 59 */ exports.formatTime = (value) => { - var time = (value.h === undefined || value.m === undefined) ? exports.decodeTime(value) : value; + var time = safeTime(typeof value === "object" ? value : exports.decodeTime(value)); + if (time.d != 0) throw "(d)ays not supported here"; + if (time.h < 0 || time.h > 23) throw "Invalid value: must be 0 <= h <= 23"; + if (time.m < 0 || time.m > 59) throw "Invalid value: must be 0 <= m <= 59"; return time.h + ":" + ("0" + time.m).substr(-2); } /** - * @param {object|int} value {h,m} object or milliseconds - * @returns an human-readable duration string like "1h 10m" + * @param {object|int} value {d, h, m, s} object or milliseconds + * @returns an human-readable duration string like "3d 1h 10m 45s" */ exports.formatDuration = (value) => { - var duration; - - var time = (value.h === undefined || value.m === undefined) ? exports.decodeTime(value) : value; - - if (time.h == 0) { - duration = time.m + "m" - } else { - duration = time.h + "h" + (time.m ? (" " + time.m + "m") : "") - } - - return duration + var duration = ""; + var time = safeTime(typeof value === "object" ? value : exports.decodeTime(value)); + if (time.d > 0) duration += time.d + "d "; + if (time.h > 0) duration += time.h + "h "; + if (time.m > 0) duration += time.m + "m "; + if (time.s > 0) duration += time.s + "s" + return duration.trim(); } exports.getCurrentTimeMillis = () => {