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

不使用moment.js将ISO8601时长转换为对象的实现问询

手动解析ISO8601时长为原生对象

完全理解你的需求——不想为了两次转换引入整个moment.js,而且要严格保留原始时长单位(拒绝自动把天转成月/年)。其实手动解析ISO8601时长格式并不复杂,下面给你一个轻量的原生JavaScript实现:

实现思路

ISO8601时长的结构很固定:

  • 以P开头(Period的缩写)
  • 随后是日期部分:年(Y)、月(M)、周(W)、日(D)
  • 如果包含时间部分,会以T开头,接着是时(H)、分(M)、秒(S)

我们可以用正则表达式匹配出每个单位对应的数值,然后组装成你需要的可访问对象。

代码实现

function parseISO8601Duration(durationStr) {
  // 匹配ISO8601时长的正则,捕获各个单位的数值
  const regex = /P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?/;
  const matches = durationStr.match(regex);

  // 初始化默认值为0,确保所有属性都存在
  const duration = {
    years: 0,
    months: 0,
    weeks: 0,
    days: 0,
    hours: 0,
    minutes: 0,
    seconds: 0
  };

  // 将捕获到的数值赋值到对应属性(注意matches数组索引从1开始)
  if (matches) {
    duration.years = parseInt(matches[1]) || 0;
    duration.months = parseInt(matches[2]) || 0;
    duration.weeks = parseInt(matches[3]) || 0;
    duration.days = parseInt(matches[4]) || 0;
    duration.hours = parseInt(matches[5]) || 0;
    duration.minutes = parseInt(matches[6]) || 0;
    duration.seconds = parseInt(matches[7]) || 0;
  }

  return duration;
}

使用示例

const duration = parseISO8601Duration('P3Y2W1DT25H5M');
console.log(duration.years); // 3
console.log(duration.weeks); // 2
console.log(duration.days); // 1
console.log(duration.hours); // 25
console.log(duration.minutes); // 5
console.log(duration.months); // 0(原字符串无月单位)
console.log(duration.seconds); // 0(原字符串无秒单位)

说明

  • 这个实现完全保留原始单位,不会做任何自动转换(比如364天就是364天,不会转成月或年)
  • 即使时长字符串缺少某些单位(比如只有日和时),返回的对象也会包含所有属性,默认值为0
  • 正则表达式已经覆盖了常见的ISO8601时长格式,包括仅日期部分、仅时间部分、混合日期时间的情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:11:33