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

如何将ISO 8601时长字符串格式化为XhYm格式?求解决建议

解决ISO 8601时长转XhYm格式的问题

嘿,我来帮你搞定这个格式转换的需求~先说说你当前代码的问题:用moment.utc(duration.asMilliseconds()).format('HH:mm')得到的是类似01:20的时间格式,不仅和你要的1h20m形式不符,而且如果时长超过24小时,HH会被重置为01,没法正确显示累计时长。下面给你几个可行的解决方案:

方案一:基于现有moment.js代码修改

既然你已经在用moment,直接利用moment.duration提供的方法来提取小时和分钟,再拼接成想要的格式就行,还能处理超过24小时的情况:

const duration = moment.duration(secondData.duration);
// 把天数转成小时,避免超过24小时时丢失时长
const totalHours = duration.days() * 24 + duration.hours();
const minutes = duration.minutes();

let formatted = '';
// 有小时就显示Xh
if (totalHours > 0) {
  formatted += `${totalHours}h`;
}
// 有分钟或者没有小时时显示Ym(比如0h30m直接显示30m)
if (minutes > 0 || totalHours === 0) {
  formatted += `${minutes}m`;
}

比如:

  • 输入PT1H20M → 输出1h20m
  • 输入P1DT2H30M(1天2小时30分)→ 输出26h30m
  • 输入PT45M → 输出45m

方案二:原生JS解析(不依赖moment)

如果不想用第三方库,用正则表达式直接解析ISO 8601时长字符串也很方便:

function formatDurationToXhYm(durationStr) {
  // 匹配ISO 8601中的天、小时、分钟(可根据需求扩展秒等单位)
  const match = durationStr.match(/P(?:(\d+)D)?T(?:(\d+)H)?(?:(\d+)M)?/);
  const days = match[1] ? parseInt(match[1], 10) : 0;
  const hours = match[2] ? parseInt(match[2], 10) : 0;
  const minutes = match[3] ? parseInt(match[3], 10) : 0;

  const totalHours = days * 24 + hours;
  let result = '';

  if (totalHours > 0) {
    result += `${totalHours}h`;
  }
  if (minutes > 0 || totalHours === 0) {
    result += `${minutes}m`;
  }

  return result;
}

// 调用示例
console.log(formatDurationToXhYm('PT1H20M')); // "1h20m"
console.log(formatDurationToXhYm('P2DT3H')); // "51h0m"(如果不想显示0m,可以加判断去掉)

如果不需要处理天的话,正则可以简化成/PT(?:(\d+)H)?(?:(\d+)M)?/。

方案三:用现代JS的Intl.DurationFormat(注意兼容性)

如果你运行代码的环境支持ES2022+,可以用原生的Intl.DurationFormat API,不过需要稍微处理一下格式:

// 先把ISO 8601时长转成Duration对象的结构(可以用moment或者正则提取)
const durationObj = moment.duration(secondData.duration).toObject();
const totalHours = durationObj.days * 24 + durationObj.hours;

const formatter = new Intl.DurationFormat('en', {
  hours: 'numeric',
  minutes: 'numeric',
  style: 'short'
});

// 把默认的"1 hr 20 min"替换成"1h20m"
const formatted = formatter.format({ hours: totalHours, minutes: durationObj.minutes })
  .replace(' hr ', 'h')
  .replace(' min', 'm');

这个方法更原生,但要注意旧版浏览器(比如IE)不支持。

内容的提问来源于stack exchange,提问作者user8991667

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:39:54