You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
blockvote/node_modules/ms/index.js

191 lines
9.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* 辅助变量定义部分。
* 这里定义了一系列时间单位换算相关的变量,方便后续在时间格式化和解析等操作中使用。
*/
// 定义变量 s 表示 1 秒对应的毫秒数,即 1000 毫秒
var s = 1000;
// 定义变量 m 表示 1 分钟对应的毫秒数,通过 1 分钟等于 60 秒来换算,即 60 * 1000 毫秒
var m = s * 60;
// 定义变量 h 表示 1 小时对应的毫秒数,通过 1 小时等于 60 分钟来换算,即 60 * 60 * 1000 毫秒
var h = m * 60;
// 定义变量 d 表示 1 天对应的毫秒数,通过 1 天等于 24 小时来换算,即 24 * 60 * 60 * 1000 毫秒
var d = h * 24;
// 定义变量 y 表示 1 年对应的毫秒数,这里取一年为 365.25 天进行换算,即 365.25 * 24 * 60 * 60 * 1000 毫秒
var y = d * 365.25;
/**
* Parse or format the given `val`.
* 此函数是模块对外暴露的主要接口,用于解析给定的 `val` 参数(如果是字符串)或者格式化给定的 `val` 参数(如果是数字)。
*
* Options:
*
* - `long` verbose formatting [false]
* 可以传入一个可选的 `options` 对象,其中 `long` 属性用于控制是否采用详细(冗长)的格式化方式,默认值为 `false`。
*
* @param {String|Number} val 要处理的参数,可以是字符串或者数字类型。
* @param {Object} [options] 可选的配置对象,用于控制格式化等相关行为。
* @throws {Error} throw an error if val is not a non-empty string or a number 如果 `val` 既不是非空字符串也不是有效的数字,会抛出一个错误。
* @return {String|Number} 根据 `val` 的类型以及 `options` 的配置,返回相应的解析或格式化后的结果,可能是字符串或者数字类型。
* @api public
*/
module.exports = function(val, options) {
// 如果没有传入 `options` 参数,则创建一个空对象作为默认值,确保后续对 `options` 属性的访问不会出现问题
options = options || {};
// 获取 `val` 的类型,通过 `typeof` 操作符判断是字符串、数字还是其他类型
var type = typeof val;
// 如果 `val` 是字符串类型且长度大于 0说明需要进行解析操作调用 `parse` 函数(内部私有函数)进行解析,并返回解析结果
if (type ==='string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isNaN(val) === false) {
// 如果 `val` 是数字类型且不是 `NaN`(即有效数字),根据 `options.long` 的值来决定调用 `fmtLong`(详细格式化)函数还是 `fmtShort`(简短格式化)函数进行格式化,并返回格式化后的结果
return options.long? fmtLong(val) : fmtShort(val);
}
// 如果 `val` 不符合上述两种合法情况(既不是非空字符串也不是有效数字),抛出一个错误,提示 `val` 的值不符合要求,并展示 `val` 的具体内容(通过 `JSON.stringify` 转换为字符串形式)
throw new Error(
'val is not a non-empty string or a valid number. val=' +
JSON.stringify(val)
);
};
/**
* Parse the given `str` and return milliseconds.
* 此函数用于解析给定的字符串 `str`,尝试从字符串中提取时间相关的数值和单位信息,并将其转换为对应的毫秒数返回。
* 如果字符串格式不符合要求或者无法正确解析,则返回 `undefined`。
*
* @param {String} str 要解析的字符串,期望包含时间数值和对应的时间单位表示(如 "1h" 表示 1 小时)。
* @return {Number} 返回解析后的毫秒数,如果解析失败则返回 `undefined`。
* @api private
*/
function parse(str) {
// 将传入的 `str` 参数强制转换为字符串类型,确保后续字符串操作的一致性
str = String(str);
// 如果字符串长度大于 100可能认为是不合理的输入直接返回不进行后续解析操作这里 100 只是一个人为设定的长度限制阈值)
if (str.length > 100) {
return;
}
// 使用正则表达式来匹配字符串中的时间数值和单位部分,尝试提取相关信息。
// 正则表达式的含义如下:
// ^ 表示匹配字符串的开头
// (?:\d+)?\.?\d+ 表示匹配可选的整数部分(可能没有)、可选的小数点以及必须的小数部分,用于提取时间数值
// * 表示前面的数值部分和后面的单位部分之间可以有零个或多个空格
// (milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)? 表示匹配可选的时间单位部分,支持多种不同的时间单位缩写形式(如 "ms"、"s"、"m"、"h"、"d"、"y" 等),并且单位部分是不区分大小写的(通过 /i 修饰符指定)
// $ 表示匹配字符串的结尾
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
str
);
if (!match) {
return;
}
// 提取匹配到的时间数值部分,并通过 `parseFloat` 转换为浮点数类型,存储在变量 `n` 中
var n = parseFloat(match[1]);
// 提取匹配到的时间单位部分,如果没有匹配到则默认使用 "ms"(毫秒),并将其转换为小写形式,存储在变量 `type` 中
var type = (match[2] || 'ms').toLowerCase();
// 根据提取到的时间单位 `type`,通过 `switch` 语句进行不同情况的处理,将对应的时间数值转换为毫秒数并返回
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return n * y;
case 'days':
case 'day':
case 'd':
return n * d;
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return n * h;
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return n * m;
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return n * s;
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return n;
default:
return undefined;
}
}
/**
* Short format for `ms`.
* 此函数用于将给定的毫秒数 `ms` 转换为简短格式的时间表示字符串,根据毫秒数的大小选择合适的时间单位进行缩写显示。
*
* @param {Number} ms 要格式化的毫秒数。
* @return {String} 返回简短格式的时间表示字符串,如 "1h"、"30m"、"10s" 等形式。
* @api private
*/
function fmtShort(ms) {
// 如果毫秒数大于等于 1 天对应的毫秒数(`d`),则将其除以 `d` 并取整,然后加上时间单位 "d"(天)返回,表示以天为单位的时间格式
if (ms >= d) {
return Math.round(ms / d) + 'd';
}
// 如果毫秒数大于等于 1 小时对应的毫秒数(`h`),则将其除以 `h` 并取整,然后加上时间单位 "h"(小时)返回,表示以小时为单位的时间格式
if (ms >= h) {
return Math.round(ms / h) + 'h';
}
// 如果毫秒数大于等于 1 分钟对应的毫秒数(`m`),则将其除以 `m` 并取整,然后加上时间单位 "m"(分钟)返回,表示以分钟为单位的时间格式
if (ms >= m) {
return Math.round(ms / m) + 'm';
}
// 如果毫秒数大于等于 1 秒对应的毫秒数(`s`),则将其除以 `s` 并取整,然后加上时间单位 "s"(秒)返回,表示以秒为单位的时间格式
if (ms >= s) {
return Math.round(ms / s) + 's';
}
// 如果毫秒数小于 1 秒对应的毫秒数,直接返回原始的毫秒数加上时间单位 "ms"(毫秒),表示以毫秒为单位的时间格式
return ms + 'ms';
}
/**
* Long format for `ms`.
* 此函数用于将给定的毫秒数 `ms` 转换为详细格式的时间表示字符串,会根据不同的时间范围使用更详细的表述方式(包含复数形式等)进行格式化。
*
* @param {Number} ms 要格式化的毫秒数。
* @return {String} 返回详细格式的时间表示字符串,如 "1 day"、"2 hours" 等形式,更符合自然语言的表述习惯。
* @api private
*/
function fmtLong(ms) {
return (
// 调用 `plural` 函数(内部私有函数)尝试按照以天为单位进行格式化,如果满足条件则返回相应的格式化字符串,否则继续后续的格式化判断
plural(ms, d, 'day') ||
// 调用 `plural` 函数尝试按照以小时为单位进行格式化,如果满足条件则返回相应的格式化字符串,否则继续后续的格式化判断
plural(ms, h, 'hour') ||
// 调用 `plural` 函数尝试按照以分钟为单位进行格式化,如果满足条件则返回相应的格式化字符串,否则继续后续的格式化判断
plural(ms, h, 'minute') ||
// 调用 `plural` 函数尝试按照以秒为单位进行格式化,如果满足条件则返回相应的格式化字符串,否则直接返回原始的毫秒数加上 " ms"(注意这里有空格)作为最后的格式化结果
plural(ms, s, 'second') ||
ms +'ms'
);
}
/**
* Pluralization helper.
* 此函数是一个辅助函数,用于根据给定的毫秒数 `ms`、时间单位对应的毫秒数 `n`(如 `d`、`h`、`m`、`s` 等)以及时间单位名称 `name`
* 来判断是否需要使用复数形式进行格式化,并返回相应的格式化字符串。
* 如果毫秒数小于对应的时间单位毫秒数 `n`,则直接返回 `undefined`,表示不满足格式化条件。
*/
function plural(ms, n, name) {
if (ms < n) {
return;
}
// 如果毫秒数小于对应时间单位毫秒数的 1.5 倍,使用 `Math.floor` 向下取整,并按照单数形式(不带 "s")进行格式化,返回如 "1 day" 的格式字符串
if (ms < n * 1.5) {
return Math.floor(ms / n) +' '+ name;
}
// 如果毫秒数大于等于对应时间单位毫秒数的 1.5 倍,使用 `Math.ceil` 向上取整,并按照复数形式(带 "s")进行格式化,返回如 "2 days" 的格式字符串
return Math.ceil(ms / n) +' '+ name +'s';
}