如何使用Ramda高效实现12小时制时间格式转换?
嘿,完全懂你这种感觉!刚上手函数式和Ramda的时候,很容易把简单问题拆得太碎,导致代码反而比命令式复杂。我来分享几个更简洁、更符合Ramda风格的实现方式,同时保持可读性:
方案一:紧凑的管道式实现
这个版本用Ramda的核心管道函数pipe串联逻辑,同时结合少量箭头函数让代码更直观:
const formatTime = R.pipe( // 拆分时间为小时和分钟数组 R.split(':'), // 调整小时部分为12小时制 R.adjust(0, hrStr => { const hr = parseInt(hrStr, 10); // 处理0点(转12)、12点以上(减12)、其他保持原样 return hr === 0 ? 12 : hr > 12 ? hr - 12 : hr; }), // 把数组转为参数,拼接成最终字符串 R.apply((hr, min) => `${hr}:${min} ${parseInt(hr, 10) >= 12 ? 'PM' : 'AM'}`) ); // 测试用例 formatTime('13:22'); // "1:22 PM" formatTime('00:30'); // "12:30 AM" formatTime('12:00'); // "12:00 PM"
方案二:纯Ramda函数组合(更函数式)
如果想尽量用Ramda的内置函数减少手动逻辑,可以把拆分逻辑成更小的纯函数,再组合起来:
// 把24小时制小时转为12小时制 const to12Hr = R.pipe( parseInt, R.cond([ [R.equals(0), R.always(12)], // 0点转12 [R.gt(R.__, 12), R.subtract(R.__, 12)], // 大于12减12 [R.T, R.identity] // 其他情况保持原样 ]) ); // 获取上午/下午标识 const getMeridiem = R.pipe( parseInt, R.ifElse(R.gte(R.__, 12), R.always('PM'), R.always('AM')) ); // 主格式化函数 const formatTime = R.pipe( R.split(':'), // 同时提取处理后的小时、原始分钟、上午/下午标识 R.juxt([ R.pipe(R.head, to12Hr, String), R.nth(1), R.pipe(R.head, getMeridiem) ]), // 拼接成最终字符串 R.apply((hr, min, meridiem) => `${hr}:${min} ${meridiem}`) ); // 测试用例 formatTime('13:22'); // "1:22 PM" formatTime('09:45'); // "9:45 AM" formatTime('24:00'); // "12:00 PM"(如果需要24点转12AM,可调整to12Hr的cond)
对你原有代码的小优化提示
- 你用
R.identity('AM')其实没必要,R.always('AM')才是返回固定字符串的正确方式(identity是返回输入参数,这里你并没有用到传入的x); parseInt最好加上第二个参数10,避免遇到带前导零的字符串时自动解析为八进制;- 函数式编程不必追求“全Ramda函数”,适当结合箭头函数能让代码更易读,尤其是简单逻辑场景。
内容的提问来源于stack exchange,提问作者cdoshi
相关产品推荐
相关产品推荐

