# How to Format std::chrono Types Using fmtlib

> Easily format C++ chrono types with fmtlib. Learn how to use fmt/chrono.h to format durations and time points using specifiers and strftime patterns for clear, readable output.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: how-to-guide
- Published: 2026-09-10

---

**fmtlib provides full formatting support for C++ chrono types through the [`fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/fmt/chrono.h) header, allowing you to format `std::chrono::duration` with specifiers like `%Q` and `%q`, and `std::chrono::time_point` using standard `strftime`-compatible patterns.**

Formatting time values in C++ typically requires verbose stream manipulators or C-style format strings, but the fmtlib library eliminates this complexity with dedicated chrono support. By including the [`fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/fmt/chrono.h) header from the fmtlib/fmt repository, you gain access to type-safe formatting for durations, time points, and clocks. This guide demonstrates how to format std::chrono types using fmtlib with practical examples derived from the source code.

## Include the fmt/chrono.h Header

All chrono formatting capabilities reside in a single header. Add the following include to your source file:

```cpp
#include <fmt/chrono.h>

```

This header provides specializations of `formatter<T>` for `std::chrono::duration` and `std::chrono::time_point` types. When you pass chrono objects to `fmt::format`, the library automatically selects the appropriate formatter, parses the format string, and drives the output generation.

## Format std::chrono::duration Values

Durations represent time intervals. The implementation in [`include/fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h) provides the `%Q` specifier for the numeric value and `%q` for the unit suffix.

### Basic Duration Formatting

Use `{:%Q}` to extract just the numeric value, or `{:%Q %q}` to include the unit:

```cpp
#include <fmt/chrono.h>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono_literals;
    std::chrono::duration<double> d = 1.2345s;

    // Numeric value only
    std::cout << fmt::format("{:%Q}", d) << '\n';     // 1.2345
    
    // Value with unit
    std::cout << fmt::format("{:%Q %q}", d) << '\n';  // 1.2345 s
}

```

### Precision and Fixed Formatting

For floating-point durations, you can specify precision within the format string. The library handles safe duration conversions internally through `safe_duration_cast` utilities (lines 200–260 in [`chrono.h`](https://github.com/fmtlib/fmt/blob/main/chrono.h)) to prevent overflow:

```cpp
// Fixed precision with 3 decimal places
std::cout << fmt::format("{:%Q.3f}", d) << '\n';  // 1.235

```

## Format std::chrono::time_point Objects

Time points represent specific moments in time. The formatting implementation uses `strftime`-compatible specifiers processed by the `tm_writer` class (starting at line 440 in [`chrono.h`](https://github.com/fmtlib/fmt/blob/main/chrono.h)).

### System Clock Time Points

Format `std::chrono::system_clock::now()` using standard date and time specifiers:

```cpp
#include <fmt/chrono.h>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono;
    auto now = system_clock::now();

    // ISO-8601 format
    std::cout << fmt::format("{:%F %T}", now) << '\n';  
    // Output: 2026-09-10 14:23:07
    
    // Custom format with weekday and month name
    std::cout << fmt::format("{:%a, %b %d %Y %H:%M}", now) << '\n';
    // Output: Sat, Sep 10 2026 14:23
}

```

### UTC and Local Time with Subseconds

The library supports `utc_clock` and local time variants. For subsecond precision, the implementation uses `write_fractional_seconds` and `write_floating_seconds` (lines 660–720 in [`chrono.h`](https://github.com/fmtlib/fmt/blob/main/chrono.h)):

```cpp
#include <fmt/chrono.h>
#include <chrono>
#include <iostream>

int main() {
    using namespace std::chrono;
    utc_time<microseconds> utc_tp = utc_clock::now();

    // Include microseconds
    std::cout << fmt::format("{:%F %T.%Q}", utc_tp) << '\n';
    // Output: 2026-09-10 14:23:07.123456
}

```

## Implementation Overview

The chrono formatting system in [`include/fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h) relies on several key components to ensure safety and performance:

- **parse_chrono_format** (lines 28–73): Parses `%`-based format strings and delegates conversions to handler callbacks.
- **tm_writer** (line ~440): Receives callbacks like `on_year`, `on_month`, and `on_second` to write formatted characters into the output buffer.
- **safe_duration_cast** (lines 200–260): Ensures conversions between different `duration` types never overflow or lose precision during formatting.

These components work together within the generic `formatter<T>` specializations to provide zero-overhead, type-safe formatting.

## Summary

- Include [`fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/fmt/chrono.h) to enable chrono formatting support in fmtlib.
- Use `%Q` for duration values and `%q` for unit suffixes when formatting `std::chrono::duration`.
- Apply standard `strftime` specifiers (like `%Y`, `%m`, `%d`, `%H`, `%M`, `%S`) to `std::chrono::time_point` objects.
- Access subsecond precision through fractional second specifiers supported by the internal `write_fractional_seconds` implementation.
- The formatting system prevents overflow through `safe_duration_cast` utilities during type conversions.

## Frequently Asked Questions

### What header do I need to include to format chrono types with fmtlib?

You must include `<fmt/chrono.h>`. This header provides the necessary `formatter` specializations for all `std::chrono` types including durations and time points. The rest of the fmtlib infrastructure is pulled in automatically when you include this file.

### Can I format std::chrono::duration with custom precision?

Yes. For floating-point durations, you can specify precision directly in the format string using syntax like `{:%Q.3f}`. The library uses internal utilities like `write_floating_seconds` (located around lines 660–720 in [`include/fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h)) to handle the fractional part formatting safely.

### Does fmtlib support UTC and local time points?

Yes. The library provides full support for `std::chrono::utc_time`, `std::chrono::local_time`, and `std::chrono::system_clock::time_point`. All time point types use the same `strftime`-compatible formatting specifiers processed by the `tm_writer` class in [`chrono.h`](https://github.com/fmtlib/fmt/blob/main/chrono.h).

### How does fmtlib prevent overflow when formatting durations?

The implementation uses `safe_duration_cast` utilities (located around lines 200–260 in [`include/fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h)) to ensure conversions between different duration types maintain precision and avoid overflow during the formatting process.