将数据/时间转换为对musl和glibc的tm / time_point。一般的方法

时间:2017-08-17 21:35:16

标签: c++ c++11 glibc musl

我想将字符串数据转换为struct tm(c)或std::chrono::time_point。问题是我想为标准libc(glibc和musl)工作解决方案。我有树标准格式,我想解析。

  1. RFC-1123

      

    Sun,1994年11月6日08:49:37 GMT

  2. RFC-850

      

    “格林尼治标准时间周日,06-Nov-94 08:49:37”

  3. ANSI C的asctime格式

      

    Sun Nov 6 08:49:37 1994“

  4. 有什么方法可以让它发挥作用吗? std::get_time有一个bug strptime在glibc上运行良好(并且快速)但是对musl失败。

    有什么想法吗?我不想像get_time那样使用流。但如果有必要那么好。 (可以使用GCC5>和c ++ 11标准)

1 个答案:

答案 0 :(得分:1)

Howard Hinnant's free, open source, header-only, date/time library可以将这些格式解析为std::chrono::time_point,即使在有错误的get_timestrptime设施的情况下也是如此。它确实需要使用std::istringstream。这是它的样子:

#include "date.h"
#include <sstream>

std::chrono::system_clock::time_point
parse_RFC_1123(const std::string& s)
{
    std::istringstream in{s};
    std::chrono::system_clock::time_point tp;
    in >> date::parse("%a, %d %b %Y %T %Z", tp);
    return tp;
}

std::chrono::system_clock::time_point
parse_RFC_850(const std::string& s)
{
    std::istringstream in{s};
    std::chrono::system_clock::time_point tp;
    in >> date::parse("%a, %d-%b-%y %T %Z", tp);
    return tp;
}

std::chrono::system_clock::time_point
parse_asctime(const std::string& s)
{
    std::istringstream in{s};
    std::chrono::system_clock::time_point tp;
    in >> date::parse("%a %b %d %T %Y", tp);
    return tp;
}

这可以这样行使:

#include <iostream>

int
main()
{
    auto tp = parse_RFC_1123("Sun, 06 Nov 1994 08:49:37 GMT");
    using namespace date;
    std::cout << tp << '\n';
    tp = parse_RFC_850("Sunday, 06-Nov-94 08:49:37 GMT");
    std::cout << tp << '\n';
    tp = parse_asctime("Sun Nov 6 08:49:37 1994");
    std::cout << tp << '\n';
}

和输出:

1994-11-06 08:49:37.000000
1994-11-06 08:49:37.000000
1994-11-06 08:49:37.000000

解析标志%a%b通常与语言环境有关。但是,如果使用-DONLY_C_LOCALE=1编译此库,则它将变为与语言环境无关的。它应该给出相同的结果。但是从实际的角度来看,如果你编译没有 -DONLY_C_LOCALE=1并且你没有得到上面的结果,你必须向你的std :: lib供应商提交一个错误报告。

如果您使用 -DONLY_C_LOCALE=1编译并且您没有得到上述结果,请拨打我的笼子,我会在几天内(如果不是几小时)将其修复。