• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Helpers.
3 */
4
5var s = 1000;
6var m = s * 60;
7var h = m * 60;
8var d = h * 24;
9var w = d * 7;
10var y = d * 365.25;
11
12/**
13 * Parse or format the given `val`.
14 *
15 * Options:
16 *
17 *  - `long` verbose formatting [false]
18 *
19 * @param {String|Number} val
20 * @param {Object} [options]
21 * @throws {Error} throw an error if val is not a non-empty string or a number
22 * @return {String|Number}
23 * @api public
24 */
25
26module.exports = function (val, options) {
27  options = options || {};
28  var type = typeof val;
29  if (type === 'string' && val.length > 0) {
30    return parse(val);
31  } else if (type === 'number' && isFinite(val)) {
32    return options.long ? fmtLong(val) : fmtShort(val);
33  }
34  throw new Error(
35    'val is not a non-empty string or a valid number. val=' +
36      JSON.stringify(val)
37  );
38};
39
40/**
41 * Parse the given `str` and return milliseconds.
42 *
43 * @param {String} str
44 * @return {Number}
45 * @api private
46 */
47
48function parse(str) {
49  str = String(str);
50  if (str.length > 100) {
51    return;
52  }
53  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(
54    str
55  );
56  if (!match) {
57    return;
58  }
59  var n = parseFloat(match[1]);
60  var type = (match[2] || 'ms').toLowerCase();
61  switch (type) {
62    case 'years':
63    case 'year':
64    case 'yrs':
65    case 'yr':
66    case 'y':
67      return n * y;
68    case 'weeks':
69    case 'week':
70    case 'w':
71      return n * w;
72    case 'days':
73    case 'day':
74    case 'd':
75      return n * d;
76    case 'hours':
77    case 'hour':
78    case 'hrs':
79    case 'hr':
80    case 'h':
81      return n * h;
82    case 'minutes':
83    case 'minute':
84    case 'mins':
85    case 'min':
86    case 'm':
87      return n * m;
88    case 'seconds':
89    case 'second':
90    case 'secs':
91    case 'sec':
92    case 's':
93      return n * s;
94    case 'milliseconds':
95    case 'millisecond':
96    case 'msecs':
97    case 'msec':
98    case 'ms':
99      return n;
100    default:
101      return undefined;
102  }
103}
104
105/**
106 * Short format for `ms`.
107 *
108 * @param {Number} ms
109 * @return {String}
110 * @api private
111 */
112
113function fmtShort(ms) {
114  var msAbs = Math.abs(ms);
115  if (msAbs >= d) {
116    return Math.round(ms / d) + 'd';
117  }
118  if (msAbs >= h) {
119    return Math.round(ms / h) + 'h';
120  }
121  if (msAbs >= m) {
122    return Math.round(ms / m) + 'm';
123  }
124  if (msAbs >= s) {
125    return Math.round(ms / s) + 's';
126  }
127  return ms + 'ms';
128}
129
130/**
131 * Long format for `ms`.
132 *
133 * @param {Number} ms
134 * @return {String}
135 * @api private
136 */
137
138function fmtLong(ms) {
139  var msAbs = Math.abs(ms);
140  if (msAbs >= d) {
141    return plural(ms, msAbs, d, 'day');
142  }
143  if (msAbs >= h) {
144    return plural(ms, msAbs, h, 'hour');
145  }
146  if (msAbs >= m) {
147    return plural(ms, msAbs, m, 'minute');
148  }
149  if (msAbs >= s) {
150    return plural(ms, msAbs, s, 'second');
151  }
152  return ms + ' ms';
153}
154
155/**
156 * Pluralization helper.
157 */
158
159function plural(ms, msAbs, n, name) {
160  var isPlural = msAbs >= n * 1.5;
161  return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
162}
163