You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于date-fns实现hh:ss(分钟百进制)格式任务时长计算优化

优化任务时长计算方案(hh:百进制分钟格式)

问题概述

开发个人时间日志工具,需将任务的start和end(Date对象)计算为hh:ss格式时长:

  • hh:累计小时数(可超过24)
  • ss:百进制分钟数(如15分钟=25,30分钟=50)

现有方案依赖date-fns的differenceInSeconds和intervalToDuration,存在冗余计算,需要优化。

方案一:基于date-fns的高效实现

直接计算总分钟数,拆分小时和剩余分钟后转换为百进制,避免intervalToDuration处理无关时间单位的开销:

import { differenceInMinutes } from "date-fns";

const zeroPad = (num) => String(num).padStart(2, '0');

const getDuration = (task) => {
  // 计算两个时间的总分钟差
  const totalMinutes = differenceInMinutes(task.end, task.start);
  // 提取完整小时数
  const hours = Math.floor(totalMinutes / 60);
  // 计算剩余分钟对应的百进制数值
  const centiMinutes = Math.round(((totalMinutes % 60) * 100) / 60);
  return `${hours}:${zeroPad(centiMinutes)}`;
};

优势

  • 仅调用differenceInMinutes一个date-fns函数,比原方案减少一次函数调用
  • 跳过intervalToDuration对年、月、日等无关单位的计算,逻辑更直接高效

方案二:原生JavaScript实现(无依赖)

如果想完全脱离库依赖,直接通过Date对象时间戳计算:

const zeroPad = (num) => String(num).padStart(2, '0');

const getDuration = (task) => {
  // 计算毫秒级时间差
  const diffMs = task.end.getTime() - task.start.getTime();
  // 转换为总分钟数
  const totalMinutes = diffMs / (1000 * 60);
  const hours = Math.floor(totalMinutes / 60);
  const centiMinutes = Math.round(((totalMinutes % 60) * 100) / 60);
  return `${hours}:${zeroPad(centiMinutes)}`;
};

优势

  • 无外部依赖,性能最优
  • 代码量与date-fns方案相当,无需额外引入库

方案验证

两种方案均能输出预期结果:

开始时间结束时间结果
2022年11月17日 08:002022年11月17日 09:151:25
2022年11月17日 08:002022年11月17日 11:453:75
2022年11月17日 08:002022年11月17日 08:300:50
2022年11月17日 08:002022年11月18日 11:0027:00

注意事项

  • 如果时间选择器仅支持15分钟步进,可去掉Math.round(结果天然为整数);若允许任意分钟输入,Math.round可保证百进制数值的精度
  • 原生方案需确保task.start和task.end为有效Date对象,避免时间戳计算出错

内容的提问来源于stack exchange,提问作者Benjamin Dubé

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:05:46