当前位置: 首页 > 知识库问答 >
问题:

解析ISO 8601持续时间

萧伟兆
2023-03-14

在ISO 8601中,持续时间的格式为<code>P[n]Y[n]M[n]DT[n]H[n]M[n]S。

例子:

20秒:

PT20.0S

一年两个月三天四小时五分钟六秒:

P1Y2M3DT4H5M6S

问题:

给定一个包含iso 8601格式的持续时间的字符串。我想获得这段时间的总秒数。标准C 11中推荐的实现方式是什么?

备注:

例如,boost DateTime中有ptime from _ iso _ string(STD::string)不适合此处。不手工做一个正则表达式有类似的方法吗?

共有2个答案

司寇凯
2023-03-14

ISO 8601 持续时间到 Unix 纪元时间转换器的示例代码:

#include <iostream>
#include <vector>
#include <regex>

using namespace std;

void match_duration(const std::string& input, const std::regex& re)
{
    std::smatch match;
    std::regex_search(input, match, re);
    if (match.empty()) {
        std::cout << "Pattern do NOT match" << std::endl;
        return;
    }

    std::vector<double> vec = {0,0,0,0,0,0}; // years, months, days, hours, minutes, seconds

    for (size_t i = 1; i < match.size(); ++i) {

        if (match[i].matched) {
            std::string str = match[i];
            str.pop_back(); // remove last character.
            vec[i-1] = std::stod(str);
        }
    }

    int duration = 31556926   * vec[0] +  // years  
                   2629743.83 * vec[1] +  // months
                   86400      * vec[2] +  // days
                   3600       * vec[3] +  // hours
                   60         * vec[4] +  // minutes
                   1          * vec[5];   // seconds

    if (duration == 0) {
        std::cout << "Not valid input" << std::endl;
        return;
    }

    std::cout << "duration: " << duration << " [sec.]" << std::endl;
}

int main()
{
    std::cout << "-- ISO 8601 duration to Unix epoch time converter--" << std::endl;
    std::cout << "Enter duration (q for quit)" << std::endl;

    std::string input;
    //input = "P1Y2M3DT4H5M6S";
    //input = "PT4H5M6S";
    //
    while(true)
    {
        std::cin >> input;
        if (!std::cin)
            break;
        if (input == "q")
            break;

        std::regex rshort("^((?!T).)*$");

        if (std::regex_match(input, rshort)) // no T (Time) exist
        {
            std::regex r("P([[:d:]]+Y)?([[:d:]]+M)?([[:d:]]+D)?");
            match_duration(input, r);
        }
        else {

            std::regex r("P([[:d:]]+Y)?([[:d:]]+M)?([[:d:]]+D)?T([[:d:]]+H)?([[:d:]]+M)?([[:d:]]+S|[[:d:]]+\\.[[:d:]]+S)?");
            match_duration(input, r);
        }
    }

    return 0;
  }
孟浩然
2023-03-14

使用标准的regex库,你想要的regex是这样的:

"P\(\([0-9]+\)Y\)?\(\([0-9]+\)M\)?\(\([0-9]+\)D\)?T\(\([0-9]+\)H\)?\(\([0-9]+\)M\)?\(\([0-9]+\(\.[0-9]+\)?S\)?"

从中,您可以提取出年数,月数等并计算总秒数。

 类似资料:
  • 我有ISO8601格式的持续时间值,我将其转换为时间值为整数秒,如下所示: ISO8601格式的持续时间值=“P1Y”。 我将该值存储在“时间-单位-秒”中。因此,当我检索的值将是在int,我想转换回ISO8601持续时间格式,所以我应该得到“P1Y”转换后回来。 有没有快速的方法可以做到这一点?或者我必须把时间的int值转换成float,然后通过某种方法把它转换成ISO8601持续时间。

  • 在ISO 8601中,持续时间的格式为PT5M(5分钟)或PT2H5M(2小时5分钟)。我有一个JSON文件,其中包含这种格式的值。我想知道spark是否可以提取分钟的持续时间。我尝试将其读取为“DateType”,并使用“minutes”函数获取分钟数,结果返回空值。 示例json 目前,我正在将其作为字符串读取并使用“regex_extract”函数。我想知道一种更有效的方法。 https:/

  • 问题内容: 我需要将持续时间字符串解析为毫秒形式。 我希望像这样的持续时间相等,但是我什么也找不到。有人会建议为此目的使用或支持SDF吗? 我目前的计划是使用正则表达式来匹配数字并做类似的事情 然后使用TimeUnit将它们放在一起并转换为毫秒。 我想我的问题是,这似乎有点过头了,它可以轻松完成吗?出现了很多有关日期和时间戳的问题,但这也许有些不同。 问题答案: 使用a 是一种合理的方法。但是,为

  • 有没有什么简单的方法可以将ISO 8601字符串持续时间(< code > P(n)Y(n)M(n)DT(n)H(n)M(n)S )转换为< code >时间。持续时间? 来自维基百科的ISO 8601持续时间: 例如,“P3Y6M4DT12H30M5S”表示“三年、六个月、四天、十二小时、三十分钟和五秒”的持续时间。

  • 我有一个ISO 8601格式的持续时间,例如:PT5M或PT120S。 有没有什么方法可以使用moment.js解析这些并获取持续时间中指定的分钟数? 谢谢大家! PS:我研究了解析ISO 8601持续时间,并将ISO 8601时间格式转换为正常持续时间 但很想知道这是否可行。

  • 我想将任何持续时间/周期字符串文字(以下面示例中显示的格式)解析为Java中的周期/持续时间实例。 所谓持续时间/周期,我指的是包含基于日期和基于时间的数量的时间量。在Java中,仅适用于基于时间的量,如秒、分钟和小时,而,仅适用于日期量,如年、月和日。 要解析的字符串并不总是包含所有量。 例子: < li> < li> < li> < li> 如果可能的话,我会怎么做?