【问题标题】:convert data/time to tm/time_point against musl and glibc. Common way针对 musl 和 glibc 将数据/时间转换为 tm/time_point。一般的方法
【发布时间】:2017-08-17 21:35:16
【问题描述】:

我想将字符串数据转换为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 有一个 bug
strptime 在 glibc 上工作得很好(而且很快),但在 musl 上失败了。

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

【问题讨论】:

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


    【解决方案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供应商提交一个错误报告。

    如果你编译 with -DONLY_C_LOCALE=1 并且你没有得到上面的结果,摇晃我的笼子,我会在几天甚至几小时内把它修好。

    【讨论】:

    • 感谢您的回答!我对你的功能做了一些基准测试。我不明白为什么您的解决方案在 RFC850 案例中比 sprintf 更快。即使您使用流。基准可以在here找到。
    • 对于 RFC 850,无论有无 -DONLY_C_LOCALE=1,我都没有得到相同的结果。我想提交错误。但不知道谁是我的 std::lib 供应商。如果我使用 GCC 7,我应该在那里报告吗?
    • 更重要的是,我的基准测试错误,RFC850 解析器失败,因为它比strptime 更快。不,它更慢,但工作正常。
    猜你喜欢
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2020-01-16
    • 2022-01-24
    • 2012-09-13
    • 2017-06-28
    • 2019-03-24
    相关资源
    最近更新 更多