Ramda 时间格式化

265 阅读2分钟

需求

接口返回秒数时长(有时是小数)转成 (hh:)mm:ss 显示在页面。

思路

先从得到 mm:ss 开始吧。

  1. 数字转整数。
  2. 转成数组 [分,秒],算分钟用时长除以 60 再取整数部分,秒就是对 60 取余。
  3. 数字数组映射成字符串数组,最终用冒号拼接。

尝试

比如 152。

除以 60 得 2.53333,再取整数部分得 2;对 60 取余得 32,

再将 [2,32] 转成 '02:32'

const padZero = s => s.padStart(2, '0');

const mmss = R.compose(
  R.join(':'),
  R.map(R.compose( padZero, String )),
  R.juxt([
    R.compose( Math.trunc, R.divide(R.__, 60) ),
    R.modulo(R.__, 60),
  ]),
  Math.trunc
);

mmss(152); // '02:32'

铺垫

搞定 分秒,该 时分 了。比方 70 分钟,对应的 hh:ss 是 01:10。

到这里我们发现,转 分秒时分 的逻辑相同:数字转成数组 [高位,低位],算高位就是除以 60 并取整数部分,低位就是对 60 取余。

现在将 得出高低位数组格式化 分成两个函数:

const padZero = s => s.padStart(2, '0');

/**
 * 时间格式化
 * @type {function(number[]): string}
 */
const timeFormatter = R.compose( R.join(':'), R.map(R.compose( padZero, String )) );

/** 时长转高低位 */
const timeHighLow = R.compose(
  R.juxt([
    R.compose( Math.trunc, R.divide(R.__, 60) ),
    R.modulo(R.__, 60),
  ]),
  Math.trunc
);

时分秒

转 hh:mm:ss 的思路:

  1. 将时长转 [分,秒]
  2. 再将分钟转成 [时,分],拼接三者成 [时,分,秒]
  3. 最后转换成 hh:mm:ss。

大致就是:

timeHighLow(10086); // [168, 6]
timeHighLow(168);   // [2, 48]
// 拼接成 [2,48,6]
// 最后得到 '02:48:06'

原数组首元素拿去处理得新数组,再拼接剩余部分,实现如下:

const hhmmss = R.compose(
  R.converge(R.concat, [R.compose( timeHighLow, R.head ), R.tail]),
  timeHighLow
);

hhmmss(168); // [0,2,48]
mmss(168);   // [2,48]

完整

export const padZero = s => s.padStart(2, '0');

/**
 * 指定高低位转换函数,生成格式化时间
 * @param {function(number): number[]} f 转换时长的函数
 * @returns {string} (hh:)mm:ss
 */
export const CustomTimeFormatter = f => R.compose(
  R.join(':'),
  R.map(R.compose( padZero, String )),
  f
);

export const timeHighLow = R.compose(
  R.juxt([
    R.compose( Math.trunc, R.divide(R.__, 60) ),
    R.modulo(R.__, 60),
  ]),
  Math.trunc
);

export const mmss = timeHighLow;

export const hhmmss = R.compose(
  R.converge(R.concat, [R.compose( timeHighLow, R.head ), R.tail]),
  timeHighLow
);

使用

import { CustomTimeFormatter, mmss, hhmmss } from '@/util/time.js';

const mmssFormatter = CustomFormatter(mmss);
const hhmmssFormatter = CustomFormatter(hhmmss);

mmssFormatter(10086);   // '168:06'
hhmmssFormatter(10086); // '02:48:06'

mmssFormatter(152);     // '02:32'
hhmmssFormatter(152);   // '00:02:32'