「30s代码解析挑战」格式化时间戳

191 阅读1分钟

解析30 seconds of code网站代码片段之「格式化时间戳」

格式化时间戳

const formatDuration = ms => {
  if (ms < 0) ms = -ms;
  
  const time = {
    day: Math.floor(ms / 86400000),
    hour: Math.floor(ms / 3600000) % 24,
    minute: Math.floor(ms / 60000) % 60,
    second: Math.floor(ms / 1000) % 60,
    millisecond: Math.floor(ms) % 1000
  };
  
  return Object.entries(time)
    .filter(val => val[1] !== 0)
    .map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
    .join(', ');
};
formatDuration(34325055574);
// '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'

流程解析

  1. 首先是把ms除以相应的数字,转化为具体的日时分秒。为什么会➗86400000:其实很简单,换算一下,一天等于24小时,一小时等于60分钟,一分钟等于60秒,一秒等1000毫秒 —>1day=24h * 60 m * 60s * 1000ms = 86400000。后面的数字也类似。
  2. 通过Object.entries和filter过滤出数值不为0的属性。
  3. 使用map函数对每个键值对数组创造一个合适的输出格式,${val !== 1 ? 's' : ''}这部分是为了处理英文中的单复数,超过1的量词需要加s变为负数形式。
  4. 最后使用join(',')将数组连成一个字符串输出。

技术解析

输入: ms毫秒

输出:day, hour, min, s, ms

%取余运算符

首先是%表示取余运算符,比如5➗3=1...2,那么5%3=2。

Object.entries

返回一个数组,数组里的元素是对象键值对的数组,基本就是[[key, value],[key, value]]这样一个形式,适合在对对象做遍历操作。除了这种遍历方式,我们使用比较多的是for...in...。

thinking

实际使用需要注意Java语言的后端传的时间戳一般是13位的,表示毫秒级(ms)。但是C++等后端语言的时间戳一般都是10位的,表示秒级(s)。在使用时要把s转换为ms,不要直接就套用了。 实际情况遇到过几次这样的情况导致时间显示错误。