使用 date-fns 将 ISO8601 持续时间转换为打字稿中的秒数

Convert ISO8601 duration to seconds in typescript using date-fns

我有一个 ISO8601 持续时间字符串。前任。 “PT1M14S” 我想使用 typescript

中的 date-fns 包将其转换为秒(Int)

软件包提供了一个解决方案:iso8601-duration 所以我们可以做类似

的事情
import { parse, toSeconds } from 'iso8601-duration';    
toSeconds(parse("PT1M14S"))

请告诉我 date-fns 对此提供了任何解决方案

解析 ISO 持续时间是问题的一半,将值应用于日期是另一半。下面是一个简单的解析器,returns 一个形式为 {part: value} 的对象,例如:

{year: 1, month, 3, hour: 1, minute: 2}

它只有 returns 字符串中标记的属性。需要添加一些适当的字符串验证。

function parseISODuration(s) {

  // QnD validation of string, need something smarter
  // Should check tokens, order and values
  // e.g. decimals only in smallest unit, W excludes other date parts
  if (!/^P/.test(s)) return;
  
  // Split into parts
  let parts = s.match(/\d+(\.\d+)?[a-z]|T/gi);

  // Flag for date and time parts, used to disambiguate month and minute
  let inDate = true;

  // Map of part tokens to words
  let partMap = {Y:'year',M:'month',W:'week',D:'day',h:'hour',m:'minute',s:'second'}
  
  return parts.reduce((acc, part) => {
  
    // Set flag if reached a time part
    if (part == 'T') {
      inDate = false;
      return acc;
    }
    
    // Disambiguate time parts (month/minute)
    if (!inDate) {
      part = part.toLowerCase();
    }
    
    // Add part name and value as a number
    acc[partMap[part.slice(-1)]] = +part.slice(0,-1);
    return acc;
  }, {});
  
}

// Examples
['P1Y2M1.5D', 'P1Y3M26DT3M', 'PT3H2M4.5S', 'P6W'].forEach(duration =>
  console.log(`${duration} => ${JSON.stringify(parseISODuration(duration))}`)
);

将持续时间转换为毫秒并非易事,必须在开始日期的上下文中完成。一种方法是复制开始日期,添加适当的值(库当然可以提供帮助),然后计算开始日期和结束日期之间的差异。

Date 实例和库会考虑不同的月长和不同的日长(观察夏令时)等问题,但是这里有很多关于添加年、月的问题都有很好的答案,天等日期,因此不难编写自己的函数来执行此操作。