Files
2025-10-25 03:02:53 +03:00

400 lines
25 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.6Formatter")) specialization
in the chrono library ([[time.syn]](time.syn "30.2Header <chrono> synopsis"))
meets the *Formatter* requirements ([[formatter.requirements]](formatter.requirements "28.5.6.1Formatter 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.2Format 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.4The 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.12Formatting[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.11I/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);