@activecollab/components
Version:
ActiveCollab Components
109 lines (104 loc) • 4.1 kB
JavaScript
import { formatNumber } from "./currencyUtils";
/**
* @function formatHours
* @description
* Formats a decimal number representing hours into a formatted string (HH:MM) or a short form if needed.
* The input can be a number, string, or undefined. It handles various formats and can optionally add a
* leading zero to the hours component. With the new "format" argument, if set to "short" and the value is
* greater than or equal to 1000, it will return a shortened format (e.g., 1K) similar to formatNumber.
*
* @param {number | string | undefined} num - The input representing the hours.
* @param {boolean} [withLeadingZeroHours=false] - Whether to add a leading zero to the hours part.
* @param {boolean} [trimZeroMinutes=false] - Whether to remove minutes if they are zero.
* @param {"long" | "short"} [format="long"] - The format type, either "long" for full numbers or "short" for abbreviated output.
*
* @returns {string} - A formatted time string or a shortened string.
*
* @example
* formatHours(1.5) // "1:30"
* formatHours("3.5", true) // "03:30"
* formatHours(1500, false, false, "short") // "1K" (using formatNumber)
*/
export const formatHours = function (num, withLeadingZeroHours, trimZeroMinutes, format) {
if (withLeadingZeroHours === void 0) {
withLeadingZeroHours = false;
}
if (trimZeroMinutes === void 0) {
trimZeroMinutes = false;
}
if (format === void 0) {
format = "long";
}
// Handle the explicit zero case.
if (num === 0 || num === "0") {
return trimZeroMinutes ? "0" : withLeadingZeroHours ? "00:00" : "0:00";
}
if (!num) {
return "";
}
// If the input is in colon format, process it as before.
if (typeof num === "string" && num.indexOf(":") >= 0) {
// eslint-disable-next-line prefer-const
let [_hours, _minutes] = num.split(":");
if (_minutes && _minutes.length === 1 && Number(_minutes) < 10) {
_minutes = Number(_minutes) + "0";
}
if (_hours && _minutes) {
if (trimZeroMinutes && _minutes === "00") {
return withLeadingZeroHours ? withLeadingZero(_hours) : String(Number(_hours));
}
return withLeadingZeroHours ? withLeadingZero(_hours) + ":" + _minutes : _hours + ":" + _minutes;
} else if (_hours && !_minutes) {
return withLeadingZeroHours ? withLeadingZero(_hours) + ":00" : _hours + ":00";
} else if (!_hours && _minutes) {
return withLeadingZeroHours ? "00:" + _minutes : "0:" + _minutes;
} else if (!_hours && !_minutes) {
return withLeadingZeroHours ? "00:00" : "0:00";
}
return withLeadingZeroHours ? "00:" + _minutes : "0:" + _minutes;
}
// Replace comma with dot if needed.
if (typeof num === "string" && num.indexOf(",") >= 0) {
num = num.replace(",", ".");
}
const input = typeof num === "string" ? parseFloat(num) : num;
// Use short formatting if specified and the value is >= 1000.
if (format === "short" && input >= 1000) {
return formatNumber(input, ",", ".", true, 2, "short");
}
// For whole numbers.
if (!isDecimal(input)) {
if (trimZeroMinutes) {
return withLeadingZeroHours ? withLeadingZero(input) : String(Number(input));
}
return withLeadingZeroHours ? withLeadingZero(input) + ":00" : input + ":00";
}
// Process decimal hours.
const decimal = input.toFixed(2);
const time = decimal.toString().split(".");
let hours = time[0];
if (withLeadingZeroHours) {
hours = withLeadingZero(hours);
}
const minutes = time[1];
const minutesFormatted = Math.round(parseInt(minutes, 10) / 100 * 60);
if (trimZeroMinutes && minutesFormatted === 0) {
return hours;
}
return hours + ":" + withLeadingZero(minutesFormatted);
};
export const withLeadingZero = function (num, size) {
if (size === void 0) {
size = 2;
}
let s = "" + num;
while (s.length < size) s = "0" + s;
return s;
};
export const isDecimal = num => {
return !Number.isInteger(num);
};
export const isValidTime = time => {
return time === undefined || /^([01]\d|2[0-3]):([0-5]\d)$/.test(time);
};
//# sourceMappingURL=timeUtils.js.map