ms源码解析

Published: · LastMod: April 07, 2024 · 883 words

ms源码 🔗

ms是一个用于毫秒时间格式化的工具,可以在语义化的时间格式和毫秒之间进行转换。

源码地址 🔗

vercel/ms: Tiny millisecond conversion utility (github.com)

Usage 🔗

语义化时间转毫秒

1
2
3
ms('2 days')  // 172800000
ms('1d')      // 86400000
ms('10h')     // 36000000

毫秒转语义化时间

1
2
3
4
5
ms(60000)             // "1m"
ms(2 * 60000)         // "2m"
// longFormat
ms(60000, { long: true })             // "1 minute"
ms(2 * 60000, { long: true })         // "2 minutes"

源码 🔗

入口函数传入2个参数,第1个就是需要转换的值,第2个是配置参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
function(val, options) {
  options = options || {};
  var type = typeof val;
  if (type === 'string' && val.length > 0) {
    return parse(val);
  } else if (type === 'number' && isFinite(val)) {
    return options.long ? fmtLong(val) : fmtShort(val);
  }
  throw new Error(
    'val is not a non-empty string or a valid number. val=' +
      JSON.stringify(val)
  );
};
  • 如果第1个参数是string, 走parse方法
  • 如果是number, 走format方法

parse 🔗

parse中通过正则表达式把传入的语义化的参数进行分割

1
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);

目的就是把语义化的字符串中的数字和单位进行分割

正则表达式进行图形化分析

image.png

最后把拿到的数值单位对应的毫秒进行相乘

1
2
3
4
5
6
var s = 1000;
var m = s * 60;
var h = m * 60;
var d = h * 24;
var w = d * 7;
var y = d * 365.25;

这里还要注意一下

一个地球年其实是365.25天, 好吧,之前都没有注意过这个问题

fmtShort 🔗

对于的输入毫秒数, 输入语义化的字符串

1
2
ms(60000)             // "1m"
ms(2 * 60000)         // "2m"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function fmtShort(ms) {
  var msAbs = Math.abs(ms);
  if (msAbs >= d) {
    return Math.round(ms / d) + 'd';
  }
  if (msAbs >= h) {
    return Math.round(ms / h) + 'h';
  }
  if (msAbs >= m) {
    return Math.round(ms / m) + 'm';
  }
  if (msAbs >= s) {
    return Math.round(ms / s) + 's';
  }
  return ms + 'ms';
}
  • 对传入的值进行取绝对值
  • 取值后和单位毫秒数进行比对,如果大于某个单位,就会取输入值和单位毫秒数的商,最后进行四舍五入

fmtLong 🔗

对于的输入毫秒数, 输入语义化的字符串,只不过最后的单位会是完整的字符串,如果是大于1的,单位自动增加复数

1
2
ms(60000, { long: true })             // "1 minute"
ms(2 * 60000, { long: true })         // "2 minutes"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function fmtLong(ms) {
  var msAbs = Math.abs(ms);
  if (msAbs >= d) {
    return plural(ms, msAbs, d, 'day');
  }
  if (msAbs >= h) {
    return plural(ms, msAbs, h, 'hour');
  }
  if (msAbs >= m) {
    return plural(ms, msAbs, m, 'minute');
  }
  if (msAbs >= s) {
    return plural(ms, msAbs, s, 'second');
  }
  return ms + ' ms';
}

/**
 * Pluralization helper.
 */

function plural(ms, msAbs, n, name) {
  var isPlural = msAbs >= n * 1.5;
  return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
}

pluralmsAbs >= n * 1.5

这里的n 要乘以 1.5, 是为了处理Math.round的四舍五入的后的值

比如ms的值是1.2个n, 四舍五入后就是1, 自然单位就不用以复数的形式输出, 加s