Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
josuttis_nm_c20_the_complete_guide.pdf
Скачиваний:
44
Добавлен:
27.03.2023
Размер:
5.85 Mб
Скачать

11.4 I/O with Chrono Types

367

11.4 I/O with Chrono Types

C++20 provides new support for directly outputting and parsing almost all chrono types.

11.4.1 Default Output Formats

For more or less all chrono types, the standard output operator has been defined since C++20. If useful, it not only prints the value but also uses an appropriate format and the unit. Locale-dependent formatting is possible.

All calendrical types print out the value as listed with the output formats of calendrical types.

All duration types print out the value with the unit type as listed in table Output units for durations. This fits any literal operator if provided.

Unit

Output Suffix

atto

as

femto

fs

pico

ps

nano

ns

micro

µs or us

milli

ms

centi

cs

deci

ds

ratio<1>

s

deca

das

hecto

hs

kilo

ks

mega

Ms

giga

Gs

tera

Ts

peta

Ps

exa

Es

ratio<60>

min

ratio<3600>

h

ratio<86400>

d

ratio<num,1>

[num]s

ratio<num,den>

[num/den]s

 

 

Table 11.8. Output units for durations

For all standard timepoint types, an output operator prints date and optionally time in the following format:

year-month-day for an integral granularity unit implicitly convertible to days

year-month-day hour:minutes:seconds for an integral granularity unit equal to or less than days

// 2021-04-25 13:37:02.936314000
tpSys}.get_local_time();
// 2021-04-25 15:37:02.936314000 // 2021-04-25 15:37:02.936 // 2021-04-25 15:37:02 // 2021-04-25 15:37:00 // 2021-04-25 // 2021-04-22
long, std::ratio<1, 3>>>(tpSys); // 2021-04-25 13:37:02.666666
tpD{tpSys};
// ERROR: no output operator defined
// 1980-01-06 00:00:00

368

Chapter 11: Dates and Timezones for <chrono>

If the type of the timepoint value (member rep) has a floating-point type, no output operator is defined.3 For the time part, the output operator of type hh_mm_ss is used. This corresponds with the %F %T

conversion specifier for formatted output. For example:

auto tpSys = std::chrono::system_clock::now(); std::cout << tpSys << '\n';

auto tpL = chr::zoned_time{chr::current_zone(), std::cout << tpL;

std::cout << chr::floor<chr::milliseconds>(tpL); std::cout << chr::floor<chr::seconds>(tpL); std::cout << chr::floor<chr::minutes>(tpL); std::cout << chr::floor<chr::days>(tpL); std::cout << chr::floor<chr::weeks>(tpL);

auto tp3 = std::chrono::floor<chr::duration<long std::cout << tp3 << '\n';

chr::sys_time<chr::duration<double, std::milli>> std::cout << tpD << '\n';

std::chrono::gps_seconds tpGPS; std::cout << tpGPS << '\n';

auto tpStd = std::chrono::steady_clock::now();

std::cout << "tpStd: " << tpStd; // ERROR: no output operator defined

The zoned_time<> type outputs like the timepoint type extended with the abbreviated timezone name. The following timezone abbreviations are used for the standard clocks:

UTC for sys_clock, utc_clock, and file_clock

TAI for tai_clock

GPS for gps_clock

Finally, note that sys_info and local_info have output operators with an undefined format. They should only be used for debugging purposes.

11.4.2 Formatted Output

Chrono supports the new library for formatted output. That means you can use date/time types for arguments of std::format() and std::format_to().

For example:

auto t0 = std::chrono::system_clock::now();

3 This is a gap that will hopefully be fixed with C++23.

11.4 I/O with Chrono Types

369

...

auto t1 = std::chrono::system_clock::now();

std::cout << std::format("From {} to {}\nit took {}\n", t0, t1, t1-t0);

This would use the default output formats of the date/time types. For example, we might have the following output:

From 2021-04-03 15:21:33.197859000 to 2021-04-03 15:21:34.686544000 it took 1488685000ns

To improve the output, you can constrain the types or use specific conversion specifiers. Most of them (but not all) correspond with the C function strftime() and the POSIX date command. For example:

std::cout << std::format("From {:%T} to {:%T} it took {:%S}s\n", t0, t1, t1-t0);

This might have the following output then:

From 15:21:34.686544000 to 15:21:34.686544000 it took 01.488685000s

The format specifiers for chrono types are part of the syntax for standard format specifiers (each specifier is optional):

fill align width .prec L spec

fill, align, with, and prec mean the same as for standard format specifiers.

spec specifies the general notation of the formatting, starting with %.

L also as usual turns on locale-dependent formatting for specifiers that support it.

Table Conversion specifiers for chrono types lists all conversion specifiers for formatted output of date/time types with an example based on Sunday, June 9, 2019 17:33:16 and 850 milliseconds.

Without using a specific conversion specifier, the default output operator is used, which marks invalid dates. When using specific conversion specifiers, this is not the case:

std::chrono::year_month_day ymd{2021y/2/31};

// February 31, 2021

std::cout << std::format("{}", ymd);

// 2021-02-31

is not a valid ...

std::cout << std::format("{:%F}", ymd);

// 2021-02-31

 

std::cout << std::format("{:%Y-%m-%d}", ymd);

// 2021-02-31

 

If the date/time value type does not provide the necessary information for a conversion specifier, a std::format_error exception is thrown. For example, an exception is thrown when:

A year specifier is used for a month_day

A weekday specifier is used for a duration

A month or weekday name should be printed and the value is not valid

A timezone specifier is used for a local timepoint

In addition, note the following about conversion specifiers:

• A negative duration or hh_mm_ss value print the minus sign in front of the whole value. For example: std::cout << std::format("{:%H:%M:%S}", -10000s); // outputs: -02:46:40

370

 

Chapter 11: Dates and Timezones for <chrono>

 

 

 

 

Spec.

Example

Meaning

%c

Sun Jun 9 17:33:16 2019

Standard or locale’s date and time representation

Dates:

 

Standard or locale’s date representation

%x

06/09/19

%F

2019-06-09

year-month-day with four and two digits

%D

06/09/19

month/day/year with two digits

%e

9

Day with leading space if single digit

%d

09

Day as two digits

%b

Jun

Standard or locale’s abbreviated month name

%h

Jun

ditto

%B

June

Standard or locale’s month name

%m

06

Month with two digits

%Y

2019

Year with four digits

%y

19

Year without century as two digits

%G

2019

ISO-week-based year as four digits (week according to %V)

%g

19

ISO-week-based year as two digits (week according to %V)

%C

20

Century as two digits

Weekdays

and weeks:

Standard or locale’s abbreviated weekday name

%a

Sun

%A

Sunday

Standard or locale’s weekday name

%w

0

Weekday as decimal number (Sunday as 0 until Saturday as 6)

%u

7

Weekday as decimal number (Monday as 1 until Sunday as 7)

%W

22

Week of the year (00 ... 53, week 01 starts with first Monday)

%U

23

Week of the year (00 ... 53, week 01 starts with first Sunday)

%V

23

ISO week of the year (01 ... 53, week 01 has Jan. 4th)

Times:

 

Standard or locale’s time representation

%X

17:33:16

%r

05:33:16 PM

Standard or locale’s 12-hour clock time

%T

17:33:16.850

hour:minutes:seconds (locale-dependent subseconds as needed)

%R

17:33

hour:minutes with two digits each

%H

17

24-hour clock hour as two digits

%I

05

12-hour clock hour as two digits

%p

PM

AM or PM according to the 12-hour clock

%M

33

Minute with two digits

%S

16.850

Seconds as decimal number (locale-specific subseconds as needed)

Other:

 

Timezone abbreviation (may also be UTC, TAI, or GPS)

%Z

CEST

%z

+0200

Offset (hours and minutes) from UTC (%Ez or %Oz for +02:00)

%j

160

Day of the year with three digits (Jan. 1st is 001)

%q

ms

Unit suffix according to the time’s duration

%Q

63196850

Value according to the time’s duration

%n

\n

Newline character

%t

\t

Tabulator character

%%

%

% character

 

 

 

 

Table 11.9. Conversion specifiers for chrono types