2

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

  1. RFC-1123

    1994 年 11 月 6 日星期日 08:49:37 GMT

  2. RFC-850

    “格林威治标准时间 94 年 11 月 6 日星期日 08:49:37”

  3. ANSI C 的 asctime 格式

    1994 年 11 月 6 日星期日 08:49:37"

有什么办法让它工作吗?std::get_time有一个错误
strptime在 glibc 上工作正常(而且很快),但对 musl 失败。

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

4

1 回答 1

1

std::chrono::time_pointHoward Hinnantget_time免费、开源、仅标头、日期/时间库可以将这些格式解析为strptime. 它确实需要使用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没有得到上述结果,请摇晃我的笼子,我会在几天内修复它,如果不是几小时的话。

于 2017-08-19T03:46:00.407 回答