【问题标题】:Convert ISO8601 duration to seconds in typescript using date-fns使用 date-fns 在 typescript 中将 ISO8601 持续时间转换为秒
【发布时间】:2021-11-16 03:53:39
【问题描述】:

我有一个 ISO8601 持续时间字符串。前任。 “PT1M14S” 我想使用 typescript 中的 date-fns 包将其转换为秒(Int)

【问题讨论】:

    标签: javascript typescript datetime iso8601 date-fns


    【解决方案1】:

    通过包提供一个解决方案:iso8601-duration 所以我们可以做类似的事情

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

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

    【讨论】:

    • 如果您有更多信息,请将其添加到 OP,而不是作为答案。
    • 链接的实用程序似乎不正确,then.setMonth(then.getMonth() + duration.months) 不处理不同长度的飞蛾。通常有关于增加月份的业务规则,例如以这种方式将 1 个月添加到 1 月 31 日将在 3 月 2 日或 3 日结束(可能会或可能不会)。同样,由于某些地方的夏令时,在所有情况下添加 1 天并不等于添加 24 小时。加减持续时间可能不是对称的,因此如果dateA + durationA == dateBdateB - durationA == dateA 不一定为真。
    【解决方案2】:

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

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

    它只返回字符串中标记的属性。需要添加一些体面的字符串验证。

    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 实例和库会考虑不同月份长度和不同白天长度(观察夏令时)等问题,但这里有很多关于添加年、月、日的问题有很好的答案,等到某个日期,所以编写自己的函数来做到这一点并不难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 2016-11-05
      • 1970-01-01
      • 2016-05-13
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多