You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将std::chrono::milliseconds转换为ISO 8601格式字符串?date库to_stream返回空字符串问题排查

How to convert std::chrono::milliseconds to ISO 8601 formatted string (e.g. 2020-02-25T00:02:43.000Z)

Problem Description

I have a std::chrono::milliseconds object representing a Unix epoch timestamp in milliseconds, and I need to convert it to an ISO 8601 formatted string like 2020-02-25T00:02:43.000Z. I've already implemented a method GetMillisecondsFromISO5601String to parse an ISO 8601 string into std::chrono::milliseconds using the date library, but my reverse conversion method GetISO8601TimeStringFrom returns an empty string when using date::to_stream.

Here's my current code:

#include "TimeConversion.hpp"
#include <date/date.h>
using std::string;
using std::string_view;
using std::chrono::milliseconds;

string TimeConversion::GetISO8601TimeStringFrom(const milliseconds& ms) {
    std::stringstream ss;
    date::to_stream(ss, "%FT%T%z", ms);
    return ss.str();
}

milliseconds TimeConversion::GetMillisecondsFromISO5601String(string_view s) {
    std::istringstream in{ std::move(string(s)) };
    in.exceptions(std::ios::failbit);
    date::sys_time<milliseconds> tp;
    if (*s.rbegin() == 'z') {
        in >> date::parse("%FT%T%z", tp);
    } else if (*s.rbegin() == 'Z') {
        in >> date::parse("%FT%T%Z", tp);
    } else {
        in >> date::parse("%FT%T%", tp);
    }
    return tp.time_since_epoch();
}

How can I fix the GetISO8601TimeStringFrom method to correctly produce the desired ISO 8601 string?


Solution

The empty string issue stems from two critical problems in your current code:

  1. Type mismatch: date::to_stream expects a time point type (like date::sys_time<milliseconds>) as input, but you're passing a std::chrono::milliseconds — which is a duration, not a representation of a specific moment in time.
  2. Incorrect format string: Your format %FT%T%z doesn't include milliseconds (required for your target format) and outputs a timezone offset like +0000 instead of the Z suffix for UTC.

Here's the fixed version of GetISO8601TimeStringFrom, using the more concise date::format function (preferred over to_stream for most use cases):

string TimeConversion::GetISO8601TimeStringFrom(const milliseconds& ms) {
    using namespace date;
    // Convert the duration to a UTC time point (since Unix epoch)
    sys_time<milliseconds> utc_time_point{ms};
    // Format to the desired ISO 8601 format with milliseconds and Z suffix
    return format("%FT%T.%3fZ", utc_time_point);
}

Key Details:

  • Time point conversion: sys_time<milliseconds>{ms} wraps your duration into a UTC-based time point, which represents the exact moment since the Unix epoch matching your timestamp.
  • Format string breakdown:
    • %F: Shortcut for %Y-%m-%d (produces the date component like 2020-02-25)
    • %T: Shortcut for %H:%M:%S (produces the time component like 00:02:43)
    • %3f: Outputs exactly 3 digits of milliseconds (to match your 000 requirement)
    • Z: Hardcoded suffix to indicate UTC time (since sys_time is inherently UTC)

If you prefer to stick with date::to_stream instead of format, adjust the code like this:

string TimeConversion::GetISO8601TimeStringFrom(const milliseconds& ms) {
    std::stringstream ss;
    date::sys_time<milliseconds> utc_time_point{ms};
    date::to_stream(ss, "%FT%T.%3fZ", utc_time_point);
    return ss.str();
}

Verification

This code will correctly convert your milliseconds timestamp to a string like 2020-02-25T00:02:43.000Z, matching your desired ISO 8601 format.

内容的提问来源于stack exchange,提问作者Jepessen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:43:10