代码之家  ›  专栏  ›  技术社区  ›  schorsch_76

std::chrono::解析为分区时间

  •  2
  • schorsch_76  · 技术社区  · 5 月前

    我需要将带有时区的时间戳解析为c++时间点。

    我的环境是linux和gcc 14.1以及-std=c++23。

    我的定义是:

    namespace MyTime {
        using clock_t = std::chrono::system_clock;
        using duration_t = clock_t::duration;
        using time_point_t = std::chrono::zoned_time<duration_t>;
        
        time_point_t now()
        {
            return std::chrono::zoned_time{std::chrono::current_zone(), clock_t::now()};
        }
        
        std::string to_string(time_point_t tp)
        {
            std::ostringstream oss;
            oss << std::format("{0:%Y-%m-%dT%T%Z}", tp);
        
            return oss.str();
        }
        
        time_point_t from_string(std::string_view str)
        {
            std::istringstream iss{std::string(str)};
            time_point_t tp{};
            iss >> std::chrono::parse("%Y-%m-%dT%T%Z",tp);
            return tp;
        }
    }
    

    MyTime::from_string(std::string_view str) 给我一个编译错误。

    如何成功编译?

    在godbolt上看到它 https://godbolt.org/z/Ysoeqe9zz

    EDIT:错误消息。

    source>: In function 'MyTime::time_point_t MyTime::from_string(std::string_view)':
    <source>:27:30: error: no matching function for call to 'parse(const char [14], MyTime::time_point_t&)'
       27 |     iss >> std::chrono::parse("%Y-%m-%dT%T%Z",tp);
          |            ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
    In file included from /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/chrono:3360,
                     from <source>:1:
    /opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/chrono_io.h:2982:5: note: candidate: 'template<class _CharT, class _Parsable>  requires  __parsable<_Parsable, _CharT, std::char_traits<_CharT> > auto std::chrono::parse(const _CharT*, _Parsable&)'
     2982 |     parse(const _CharT* __fmt, _Parsable& __tp)
          |     ^~~~~
    
    1 回复  |  直到 5 月前
        1
  •  2
  •   Howard Hinnant    5 月前

    zoned_time 不可解析,原因很简单,解析程序通常不知道什么 time_zone 放入 分区_时间 。但这是可以解决的。

    这个 to_string 函数当前写出 时区 缩写 但是 时区 缩写在所有语言中都不是唯一的 时区 s.只有 时区 姓名 是独一无二的。所以 to_string 函数必须输出 时区 改为名称:

    std::string to_string(time_point_t tp)
    {
        std::ostringstream oss;
        oss << std::format("{:%Y-%m-%dT%T}", tp) << tp.get_time_zone()->name();
    
        return oss.str();
    }
    

    现在 from_string 函数可以将本地时间解析为 local_time ,并解析 时区 名字变成a string .然后a 分区_时间 可以由此形成 本地时间 时区 姓名:

    time_point_t from_string(std::string_view str)
    {
        std::istringstream iss{std::string(str)};
        std::chrono::local_time<duration_t> tp{};
        std::string tz_name;
        iss >> std::chrono::parse("%Y-%m-%dT%T%Z",tp,tz_name);
        return time_point_t{tz_name, tp};
    }