[time.format]

# 30 Time library [[time]](./#time)

## 30.12 Formatting [time.format]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10440)

Each formatter ([[format.formatter]](format.formatter "28.5.6 Formatter")) specialization
in the chrono library ([[time.syn]](time.syn "30.2 Header <chrono> synopsis"))
meets the *Formatter* requirements ([[formatter.requirements]](formatter.requirements "28.5.6.1 Formatter requirements"))[.](#1.sentence-1)

The parse member functions of these formatters
interpret the format specification
as a *chrono-format-spec* according to the following syntax:

chrono-format-spec :  
fill-and-alignopt widthopt precisionopt Lopt chrono-specsopt

chrono-specs :  
conversion-spec  
chrono-specs conversion-spec  
chrono-specs literal-char

literal-char :  
any character other than {, }, or %

conversion-spec :  
% modifieropt type

modifier : one of  
E O

type : one of  
a A b B c C d D e F g G h H I j m M n  
p q Q r R S t T u U V w W x X y Y z Z %

The productions*fill-and-align*,*width*, and*precision* are described in [[format.string]](format.string "28.5.2 Format string")[.](#1.sentence-3)

Giving a *precision* specification
in the *chrono-format-spec* is valid only for types that are
specializations of std​::​chrono​::​duration for which the nested [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") rep denotes
a floating-point type[.](#1.sentence-4)

For all other types,
an exception of type format_error is thrown
if the *chrono-format-spec* contains a *precision* specification[.](#1.sentence-5)

All ordinary multibyte characters
represented by *literal-char* are copied unchanged to the output[.](#1.sentence-6)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10500)

A [*formatting locale*](#def:locale,formatting "30.12 Formatting [time.format]") is an instance of locale used by a formatting function, defined as

- [(2.1)](#2.1)

the "C" locale if the L option
is not present in *chrono-format-spec*, otherwise

- [(2.2)](#2.2)

the locale passed to the formatting function if any, otherwise

- [(2.3)](#2.3)

the global locale[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10513)

Each conversion specifier *conversion-spec* is replaced by appropriate characters
as described in Table [133](#tab:time.format.spec "Table 133: Meaning of conversion specifiers");
the formats specified in ISO 8601-1:2019 shall be used where so described[.](#3.sentence-1)

Some of the conversion specifiers
depend on the formatting locale[.](#3.sentence-2)

If the string literal encoding is a Unicode encoding form and
the locale is among
an implementation-defined set of locales,
each replacement that depends on the locale is performed as if
the replacement character sequence is converted to the string literal encoding[.](#3.sentence-3)

If the formatted object does not contain the information
the conversion specifier refers to,
an exception of type format_error is thrown[.](#3.sentence-4)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10529)

The result of formatting
a std​::​chrono​::​duration instance holding a negative value, or
an hh_mm_ss object h for which h.is_negative() is true,
is equivalent to the output of the corresponding positive value,
with a *STATICALLY-WIDEN*<charT>("-") character sequence
placed before the replacement of the initial conversion specifier[.](#4.sentence-1)

[*Example [1](#example-1)*: cout << format("{:%T}", -10'000s); // prints: -02:46:40 cout << format("{:%H:%M:%S}", -10'000s); // prints: -02:46:40 cout << format("minutes {:%M, hours %H, seconds %S}", -10'000s); // prints: minutes -46, hours 02, seconds 40 â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10545)

Unless explicitly requested,
the result of formatting a chrono type
does not contain time zone abbreviation
and time zone offset information[.](#5.sentence-1)

If the information is available,
the conversion specifiers %Z and %z will format this information (respectively)[.](#5.sentence-2)

[*Note [1](#note-1)*:

If the information is not available and
a %Z or %z conversion specifier appears in
the *chrono-format-spec*,
an exception of type format_error is thrown,
as described above[.](#5.sentence-3)

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10562)

If the type being formatted does not contain
the information that the format flag needs,
an exception of type format_error is thrown[.](#6.sentence-1)

[*Example [2](#example-2)*:

A duration does not contain enough information
to format as a weekday[.](#6.sentence-2)

â *end example*]

However, if a flag refers to a âtime of dayâ
(e.g., %H, %I, %p, etc[.](#6.sentence-3))

,
then a specialization of duration is interpreted as
the time of day elapsed since midnight[.](#6.sentence-4)

Table [133](#tab:time.format.spec) — Meaning of conversion specifiers [[tab:time.format.spec]](./tab:time.format.spec)  

| [ð](#tab:time.format.spec-row-1)<br>**Specifier** | **Replacement** |
| --- | --- |
| [ð](#tab:time.format.spec-row-2)<br>%a | The locale's abbreviated weekday name[.](#tab:time.format.spec-row-2-column-2-sentence-1)<br>If the value does not contain a valid weekday, an exception of type format_error is thrown[.](#tab:time.format.spec-row-2-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-3)<br>%A | The locale's full weekday name[.](#tab:time.format.spec-row-3-column-2-sentence-1)<br>If the value does not contain a valid weekday, an exception of type format_error is thrown[.](#tab:time.format.spec-row-3-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-4)<br>%b | The locale's abbreviated month name[.](#tab:time.format.spec-row-4-column-2-sentence-1)<br>If the value does not contain a valid month, an exception of type format_error is thrown[.](#tab:time.format.spec-row-4-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-5)<br>%B | The locale's full month name[.](#tab:time.format.spec-row-5-column-2-sentence-1)<br>If the value does not contain a valid month, an exception of type format_error is thrown[.](#tab:time.format.spec-row-5-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-6)<br>%c | The locale's date and time representation[.](#tab:time.format.spec-row-6-column-2-sentence-1)<br>The modified command %Ec produces the locale's alternate date and time representation[.](#tab:time.format.spec-row-6-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-7)<br>%C | The year divided by 100 using floored division[.](#tab:time.format.spec-row-7-column-2-sentence-1)<br>If the result is a single decimal digit, it is prefixed with 0[.](#tab:time.format.spec-row-7-column-2-sentence-2)<br>The modified command %EC produces the locale's alternative representation of the century[.](#tab:time.format.spec-row-7-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-8)<br>%d | The day of month as a decimal number[.](#tab:time.format.spec-row-8-column-2-sentence-1)<br>If the result is a single decimal digit, it is prefixed with 0[.](#tab:time.format.spec-row-8-column-2-sentence-2)<br>The modified command %Od produces the locale's alternative representation[.](#tab:time.format.spec-row-8-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-9)<br>%D | Equivalent to %m/%d/%y[.](#tab:time.format.spec-row-9-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-10)<br>%e | The day of month as a decimal number[.](#tab:time.format.spec-row-10-column-2-sentence-1)<br>If the result is a single decimal digit, it is prefixed with a space[.](#tab:time.format.spec-row-10-column-2-sentence-2)<br>The modified command %Oe produces the locale's alternative representation[.](#tab:time.format.spec-row-10-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-11)<br>%F | Equivalent to %Y-%m-%d[.](#tab:time.format.spec-row-11-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-12)<br>%g | The last two decimal digits of the calendar year as specified in ISO 8601-1:2019 for the week calendar[.](#tab:time.format.spec-row-12-column-2-sentence-1)<br>If the result is a single digit it is prefixed by 0[.](#tab:time.format.spec-row-12-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-13)<br>%G | The calendar year as a decimal number, as specified in ISO 8601-1:2019 for the week calendar[.](#tab:time.format.spec-row-13-column-2-sentence-1)<br>If the result is less than four digits it is left-padded with 0 to four digits[.](#tab:time.format.spec-row-13-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-14)<br>%h | Equivalent to %b[.](#tab:time.format.spec-row-14-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-15)<br>%H | The hour (24-hour clock) as a decimal number[.](#tab:time.format.spec-row-15-column-2-sentence-1)<br>If the result is a single digit, it is prefixed with 0[.](#tab:time.format.spec-row-15-column-2-sentence-2)<br>The modified command %OH produces the locale's alternative representation[.](#tab:time.format.spec-row-15-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-16)<br>%I | The hour (12-hour clock) as a decimal number[.](#tab:time.format.spec-row-16-column-2-sentence-1)<br>If the result is a single digit, it is prefixed with 0[.](#tab:time.format.spec-row-16-column-2-sentence-2)<br>The modified command %OI produces the locale's alternative representation[.](#tab:time.format.spec-row-16-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-17)<br>%j | If the type being formatted is a specialization of duration, the decimal number of days without padding[.](#tab:time.format.spec-row-17-column-2-sentence-1)<br>Otherwise, the day of the year as a decimal number[.](#tab:time.format.spec-row-17-column-2-sentence-2)<br>January 1 is 001[.](#tab:time.format.spec-row-17-column-2-sentence-3)<br>If the result is less than three digits, it is left-padded with 0 to three digits[.](#tab:time.format.spec-row-17-column-2-sentence-4) |
| [ð](#tab:time.format.spec-row-18)<br>%m | The month as a decimal number[.](#tab:time.format.spec-row-18-column-2-sentence-1)<br>Jan is 01[.](#tab:time.format.spec-row-18-column-2-sentence-2)<br>If the result is a single digit, it is prefixed with 0[.](#tab:time.format.spec-row-18-column-2-sentence-3)<br>The modified command %Om produces the locale's alternative representation[.](#tab:time.format.spec-row-18-column-2-sentence-4) |
| [ð](#tab:time.format.spec-row-19)<br>%M | The minute as a decimal number[.](#tab:time.format.spec-row-19-column-2-sentence-1)<br>If the result is a single digit, it is prefixed with 0[.](#tab:time.format.spec-row-19-column-2-sentence-2)<br>The modified command %OM produces the locale's alternative representation[.](#tab:time.format.spec-row-19-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-20)<br>%n | A new-line character[.](#tab:time.format.spec-row-20-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-21)<br>%p | The locale's equivalent of the AM/PM designations associated with a 12-hour clock[.](#tab:time.format.spec-row-21-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-22)<br>%q | The duration's unit suffix as specified in [[time.duration.io]](time.duration.io "30.5.11 I/O")[.](#tab:time.format.spec-row-22-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-23)<br>%Q | The duration's numeric value (as if extracted via .count())[.](#tab:time.format.spec-row-23-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-24)<br>%r | The locale's 12-hour clock time[.](#tab:time.format.spec-row-24-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-25)<br>%R | Equivalent to %H:%M[.](#tab:time.format.spec-row-25-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-26)<br>%S | Seconds as a decimal number[.](#tab:time.format.spec-row-26-column-2-sentence-1)<br>If the number of seconds is less than 10, the result is prefixed with 0[.](#tab:time.format.spec-row-26-column-2-sentence-2)<br>If the precision of the input cannot be exactly represented with seconds, then the format is a decimal floating-point number with a fixed format and a precision matching that of the precision of the input (or to a microseconds precision if the conversion to floating-point decimal seconds cannot be made within 18 fractional digits)[.](#tab:time.format.spec-row-26-column-2-sentence-3)<br>The character for the decimal point is localized according to the locale[.](#tab:time.format.spec-row-26-column-2-sentence-4)<br>The modified command %OS produces the locale's alternative representation[.](#tab:time.format.spec-row-26-column-2-sentence-5) |
| [ð](#tab:time.format.spec-row-27)<br>%t | A horizontal-tab character[.](#tab:time.format.spec-row-27-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-28)<br>%T | Equivalent to %H:%M:%S[.](#tab:time.format.spec-row-28-column-2-sentence-1) |
| [ð](#tab:time.format.spec-row-29)<br>%u | The calendar day of week as a decimal number (1-7), as specified in ISO 8601-1:2019, where Monday is 1[.](#tab:time.format.spec-row-29-column-2-sentence-1)<br>The modified command %Ou produces the locale's alternative representation[.](#tab:time.format.spec-row-29-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-30)<br>%U | The week number of the year as a decimal number[.](#tab:time.format.spec-row-30-column-2-sentence-1)<br>The first Sunday of the year is the first day of week 01[.](#tab:time.format.spec-row-30-column-2-sentence-2)<br>Days of the same year prior to that are in week 00[.](#tab:time.format.spec-row-30-column-2-sentence-3)<br>If the result is a single digit, it is prefixed with 0[.](#tab:time.format.spec-row-30-column-2-sentence-4)<br>The modified command %OU produces the locale's alternative representation[.](#tab:time.format.spec-row-30-column-2-sentence-5) |
| [ð](#tab:time.format.spec-row-31)<br>%V | The calendar week of year as a decimal number, as specified in ISO 8601-1:2019 for the week calendar[.](#tab:time.format.spec-row-31-column-2-sentence-1)<br>If the result is a single digit, it is prefixed with 0[.](#tab:time.format.spec-row-31-column-2-sentence-2)<br>The modified command %OV produces the locale's alternative representation[.](#tab:time.format.spec-row-31-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-32)<br>%w | The weekday as a decimal number (0-6), where Sunday is 0[.](#tab:time.format.spec-row-32-column-2-sentence-1)<br>The modified command %Ow produces the locale's alternative representation[.](#tab:time.format.spec-row-32-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-33)<br>%W | The week number of the year as a decimal number[.](#tab:time.format.spec-row-33-column-2-sentence-1)<br>The first Monday of the year is the first day of week 01[.](#tab:time.format.spec-row-33-column-2-sentence-2)<br>Days of the same year prior to that are in week 00[.](#tab:time.format.spec-row-33-column-2-sentence-3)<br>If the result is a single digit, it is prefixed with 0[.](#tab:time.format.spec-row-33-column-2-sentence-4)<br>The modified command %OW produces the locale's alternative representation[.](#tab:time.format.spec-row-33-column-2-sentence-5) |
| [ð](#tab:time.format.spec-row-34)<br>%x | The locale's date representation[.](#tab:time.format.spec-row-34-column-2-sentence-1)<br>The modified command %Ex produces the locale's alternate date representation[.](#tab:time.format.spec-row-34-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-35)<br>%X | The locale's time representation[.](#tab:time.format.spec-row-35-column-2-sentence-1)<br>The modified command %EX produces the locale's alternate time representation[.](#tab:time.format.spec-row-35-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-36)<br>%y | The last two decimal digits of the year[.](#tab:time.format.spec-row-36-column-2-sentence-1)<br>If the result is a single digit, it is prefixed by 0[.](#tab:time.format.spec-row-36-column-2-sentence-2)<br>The modified command %Oy produces the locale's alternative representation[.](#tab:time.format.spec-row-36-column-2-sentence-3)<br>The modified command %Ey produces the locale's alternative representation of offset from %EC (year only)[.](#tab:time.format.spec-row-36-column-2-sentence-4) |
| [ð](#tab:time.format.spec-row-37)<br>%Y | The year as a decimal number[.](#tab:time.format.spec-row-37-column-2-sentence-1)<br>If the result is less than four digits, it is left-padded with 0 to four digits[.](#tab:time.format.spec-row-37-column-2-sentence-2)<br>The modified command %EY produces the locale's alternative full year representation[.](#tab:time.format.spec-row-37-column-2-sentence-3) |
| [ð](#tab:time.format.spec-row-38)<br>%z | The offset from UTC as specified in ISO 8601-1:2019, 5.3.4.1[.](#tab:time.format.spec-row-38-column-2-sentence-1)<br>For example -0430 refers to 4 hours 30 minutes behind UTC[.](#tab:time.format.spec-row-38-column-2-sentence-2)<br>If the offset is zero, +0000 is used[.](#tab:time.format.spec-row-38-column-2-sentence-3)<br>The modified commands %Ez and %Oz insert a : between the hours and minutes: -04:30[.](#tab:time.format.spec-row-38-column-2-sentence-4)<br>If the offset information is not available, an exception of type format_error is thrown[.](#tab:time.format.spec-row-38-column-2-sentence-5) |
| [ð](#tab:time.format.spec-row-39)<br>%Z | The time zone abbreviation[.](#tab:time.format.spec-row-39-column-2-sentence-1)<br>If the time zone abbreviation is not available, an exception of type format_error is thrown[.](#tab:time.format.spec-row-39-column-2-sentence-2) |
| [ð](#tab:time.format.spec-row-40)<br>%% | A % character[.](#tab:time.format.spec-row-40-column-2-sentence-1) |

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10799)

Unless otherwise specified,
if the *chrono-specs* is omitted,
the chrono object is formatted
as if by streaming it to basic_ostringstream<charT> os with the formatting locale imbued
and copying os.str() through the output iterator of the context
with additional padding and adjustments as specified by the format specifiers[.](#7.sentence-1)

[*Example [3](#example-3)*: string s = format("{:=>8}", 42ms); // value of s is "====42ms" â *end example*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10813)

For chrono​::​duration the library only provides the following specialization
of enable_nonlocking_formatter_optimization:template<class Rep, class Period>constexpr bool enable_nonlocking_formatter_optimization< chrono::duration<Rep, Period>> = enable_nonlocking_formatter_optimization<Rep>;

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10824)

For chrono​::​zoned_time the library only provides the following specialization ofenable_nonlocking_formatter_optimization:template<class Duration>constexpr bool enable_nonlocking_formatter_optimization< chrono::zoned_time<Duration, const std::chrono::time_zone*>> = true;

[ð](#lib:formatter,specializations,chrono::sys_time)

`template<class Duration, class charT>
  struct formatter<chrono::sys_time<Duration>, charT>;
`

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10841)

*Remarks*: If %Z is used,
it is replaced with *STATICALLY-WIDEN*<charT>("UTC")[.](#10.sentence-1)

If %z (or a modified variant of %z) is used,
an offset of 0min is formatted[.](#10.sentence-2)

[ð](#lib:formatter,specializations,chrono::utc_time)

`template<class Duration, class charT>
  struct formatter<chrono::utc_time<Duration>, charT>;
`

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10856)

*Remarks*: If %Z is used,
it is replaced with *STATICALLY-WIDEN*<charT>("UTC")[.](#11.sentence-1)

If %z (or a modified variant of %z) is used,
an offset of 0min is formatted[.](#11.sentence-2)

If the argument represents a time during a positive leap second insertion,
and if a seconds field is formatted,
the integral portion of that format is*STATICALLY-WIDEN*<charT>("60")[.](#11.sentence-3)

[ð](#lib:formatter,specializations,chrono::tai_time)

`template<class Duration, class charT>
  struct formatter<chrono::tai_time<Duration>, charT>;
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10875)

*Remarks*: If %Z is used,
it is replaced with *STATICALLY-WIDEN*<charT>("TAI")[.](#12.sentence-1)

If %z (or a modified variant of %z) is used,
an offset of 0min is formatted[.](#12.sentence-2)

The date and time formatted are equivalent to
those formatted by a sys_time initialized withsys_time<Duration>{tp.time_since_epoch()} -(sys_days{1970y/January/1} - sys_days{1958y/January/1})

[ð](#lib:formatter,specializations,chrono::gps_time)

`template<class Duration, class charT>
  struct formatter<chrono::gps_time<Duration>, charT>;
`

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10896)

*Remarks*: If %Z is used,
it is replaced with *STATICALLY-WIDEN*<charT>("GPS")[.](#13.sentence-1)

If %z (or a modified variant of %z) is used,
an offset of 0min is formatted[.](#13.sentence-2)

The date and time formatted are equivalent to
those formatted by a sys_time initialized withsys_time<Duration>{tp.time_since_epoch()} +(sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1})

[ð](#lib:formatter,specializations,chrono::file_time)

`template<class Duration, class charT>
  struct formatter<chrono::file_time<Duration>, charT>;
`

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10917)

*Remarks*: If %Z is used,
it is replaced with *STATICALLY-WIDEN*<charT>("UTC")[.](#14.sentence-1)

If %z (or a modified variant of %z) is used,
an offset of 0min is formatted[.](#14.sentence-2)

The date and time formatted are equivalent to
those formatted
by a sys_time initialized with clock_cast<system_clock>(t), or
by a utc_time initialized with clock_cast<utc_clock>(t),
where t is the first argument to format[.](#14.sentence-3)

[ð](#lib:formatter,specializations,chrono::local_time)

`template<class Duration, class charT>
  struct formatter<chrono::local_time<Duration>, charT>;
`

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10937)

*Remarks*: If %Z, %z, or a modified version of %z is used,
an exception of type format_error is thrown[.](#15.sentence-1)

[ð](#lib:local-time-format-t)

template<class Duration> struct *local-time-format-t* { // *exposition only* local_time<Duration> time; // *exposition only*const string* abbrev; // *exposition only*const seconds* offset_sec; // *exposition only*};

[ð](#lib:local_time_format)

`template<class Duration>
  local-time-format-t<Duration>
    local_time_format(local_time<Duration> time, const string* abbrev = nullptr,
                      const seconds* offset_sec = nullptr);
`

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10961)

*Returns*: {time, abbrev, offset_sec}[.](#16.sentence-1)

[ð](#lib:formatter,specializations,chrono::local-time-format-t)

`template<class Duration, class charT>
  struct formatter<chrono::local-time-format-t<Duration>, charT>;
`

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10973)

Let f be a *local-time-format-t*<Duration> object
passed to formatter​::​format[.](#17.sentence-1)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L10977)

*Remarks*: If the *chrono-specs* is omitted,
the result is equivalent to using %F %T %Z as
the *chrono-specs*[.](#18.sentence-1)

If %Z is used,
it is replaced with *f.abbrev if f.abbrev is not a null pointer value[.](#18.sentence-2)

If %Z is used
and f.abbrev is a null pointer value,
an exception of type format_error is thrown[.](#18.sentence-3)

If %z (or a modified variant of %z) is used,
it is formatted with the value of *f.offset_sec if f.offset_sec is not a null pointer value[.](#18.sentence-4)

If %z (or a modified variant of %z) is used
and f.offset_sec is a null pointer value,
then an exception of type format_error is thrown[.](#18.sentence-5)

[ð](#lib:formatter,specializations,chrono::zoned_time)

template<class Duration, class TimeZonePtr, class charT>struct formatter<chrono::zoned_time<Duration, TimeZonePtr>, charT>: formatter<chrono::*local-time-format-t*<common_type_t<Duration, seconds>>, charT> {template<class FormatContext>typename FormatContext::iterator
 format(const chrono::zoned_time<Duration, TimeZonePtr>& tp, FormatContext& ctx) const;};

[ð](#lib:format,formatter%3cchrono::zoned_time%3e)

`template<class FormatContext>
  typename FormatContext::iterator
    format(const chrono::zoned_time<Duration, TimeZonePtr>& tp, FormatContext& ctx) const;
`

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/time.tex#L11015)

*Effects*: Equivalent to:sys_info info = tp.get_info();return formatter<chrono::*local-time-format-t*<common_type_t<Duration, seconds>>, charT>:: format({tp.get_local_time(), &info.abbrev, &info.offset}, ctx);
