std::chrono Support¶
Glaze provides first-class support for std::chrono types, enabling seamless serialization and deserialization of durations and time points.
Supported Types¶
Durations¶
All std::chrono::duration types are supported and serialize as their numeric count value:
std::chrono::milliseconds ms{12345};
std::string json = glz::write_json(ms).value(); // "12345"
std::chrono::milliseconds parsed{};
glz::read_json(parsed, json); // parsed.count() == 12345
This works with any duration type, including custom periods:
std::chrono::seconds s{3600}; // "3600"
std::chrono::nanoseconds ns{123456789}; // "123456789"
std::chrono::hours h{24}; // "24"
// Custom period (e.g., 60fps frames)
using frames = std::chrono::duration<int64_t, std::ratio<1, 60>>;
frames f{120}; // "120"
// Floating-point rep
std::chrono::duration<double, std::milli> ms{123.456}; // "123.456"
System Clock Time Points¶
std::chrono::system_clock::time_point serializes as an ISO 8601 string in UTC:
auto now = std::chrono::system_clock::now();
std::string json = glz::write_json(now).value();
// "2024-12-13T15:30:45.123456789Z"
The precision of fractional seconds matches the time point's duration type:
using namespace std::chrono;
sys_time<seconds> tp_sec{...}; // "2024-12-13T15:30:45Z"
sys_time<milliseconds> tp_ms{...}; // "2024-12-13T15:30:45.123Z"
sys_time<microseconds> tp_us{...}; // "2024-12-13T15:30:45.123456Z"
sys_time<nanoseconds> tp_ns{...}; // "2024-12-13T15:30:45.123456789Z"
Parsing supports multiple ISO 8601 formats:
std::chrono::system_clock::time_point tp;
// UTC with Z suffix
glz::read_json(tp, "\"2024-12-13T15:30:45Z\"");
// With timezone offset
glz::read_json(tp, "\"2024-12-13T15:30:45+05:00\"");
glz::read_json(tp, "\"2024-12-13T15:30:45-08:00\"");
// With fractional seconds
glz::read_json(tp, "\"2024-12-13T15:30:45.123456789Z\"");
Steady Clock Time Points¶
std::chrono::steady_clock::time_point serializes as a numeric count (time since epoch), since steady clock's epoch is implementation-defined and not meaningful as a calendar time:
auto start = std::chrono::steady_clock::now();
std::string json = glz::write_json(start).value(); // numeric count
std::chrono::steady_clock::time_point parsed;
glz::read_json(parsed, json);
// Exact roundtrip - no precision loss
Epoch Time Wrappers¶
For APIs that expect Unix timestamps (numeric epoch time) instead of ISO 8601 strings, Glaze provides epoch_time<Duration> wrappers:
#include "glaze/glaze.hpp"
// Convenience aliases
glz::epoch_seconds // Unix timestamp in seconds
glz::epoch_millis // Unix timestamp in milliseconds
glz::epoch_micros // Unix timestamp in microseconds
glz::epoch_nanos // Unix timestamp in nanoseconds
Usage¶
glz::epoch_seconds ts;
ts.value = std::chrono::system_clock::now();
std::string json = glz::write_json(ts).value(); // "1702481400"
glz::epoch_seconds parsed;
glz::read_json(parsed, json);
Implicit Conversion¶
epoch_time wrappers implicitly convert to/from system_clock::time_point:
glz::epoch_millis ts = std::chrono::system_clock::now();
std::chrono::system_clock::time_point tp = ts;
In Structs¶
Use epoch wrappers when your API requires numeric timestamps:
struct ApiResponse {
std::string data;
glz::epoch_millis created_at; // Serializes as: 1702481400123
glz::epoch_millis updated_at;
};
struct Event {
std::string name;
std::chrono::system_clock::time_point timestamp; // ISO 8601 string
std::chrono::milliseconds duration; // Numeric count
};
Complete Example¶
#include "glaze/glaze.hpp"
#include <chrono>
struct LogEntry {
std::string message;
std::chrono::system_clock::time_point timestamp;
std::chrono::microseconds processing_time;
};
struct MetricsReport {
glz::epoch_millis generated_at;
std::chrono::steady_clock::time_point uptime_start;
std::vector<LogEntry> entries;
};
int main() {
MetricsReport report;
report.generated_at = std::chrono::system_clock::now();
report.uptime_start = std::chrono::steady_clock::now();
report.entries.push_back({
"Request processed",
std::chrono::system_clock::now(),
std::chrono::microseconds{1234}
});
// Serialize
std::string json = glz::write_json(report).value();
// Deserialize
MetricsReport parsed;
glz::read_json(parsed, json);
}
Output:
{
"generated_at": 1702481400123,
"uptime_start": 123456789012345,
"entries": [
{
"message": "Request processed",
"timestamp": "2024-12-13T15:30:45.123456Z",
"processing_time": 1234
}
]
}
Summary Table¶
| Type | JSON Format | Example |
|---|---|---|
std::chrono::duration<Rep, Period> |
Numeric count | 12345 |
std::chrono::system_clock::time_point |
ISO 8601 string | "2024-12-13T15:30:45Z" |
std::chrono::steady_clock::time_point |
Numeric count | 123456789012345 |
glz::epoch_seconds |
Unix seconds | 1702481400 |
glz::epoch_millis |
Unix milliseconds | 1702481400123 |
glz::epoch_micros |
Unix microseconds | 1702481400123456 |
glz::epoch_nanos |
Unix nanoseconds | 1702481400123456789 |
Notes¶
- Thread Safety: All chrono serialization is fully thread-safe with no static buffers
- Precision: Roundtrip serialization preserves full precision for all supported types
- Validation: Invalid ISO 8601 strings return
glz::error_code::parse_error - Timezone Handling: Time points are always converted to/from UTC; timezone offsets in input are properly applied
- Leap Seconds: Not supported (
23:59:60will return a parse error).std::chrono::system_clockuses Unix time which does not account for leap seconds