C++20: Chrono I/O: Unformatiert und formatiert

Die verschiedenen Datentypen unterstützen das formatierte Schreiben mit der neuen Formatierungsbibliothek.​

In Pocket speichern vorlesen Druckansicht
Bahnhofsuhr

(Bild: MediaPortal der Deutschen Bahn)

Lesezeit: 2 Min.
Von
  • Rainer Grimm
Inhaltsverzeichnis

Dieser Artikel ist der zehnte in meiner ausführlichen Reise durch die Chrono-Erweiterung in C++20:

Modernes C++ – Rainer Grimm

Rainer Grimm ist seit vielen Jahren als Softwarearchitekt, Team- und Schulungsleiter tätig. Er schreibt gerne Artikel zu den Programmiersprachen C++, Python und Haskell, spricht aber auch gerne und häufig auf Fachkonferenzen. Auf seinem Blog Modernes C++ beschäftigt er sich intensiv mit seiner Leidenschaft C++.

Die meisten Datentypen von Chrono wie Zeitdauer, Zeitpunkte und Kalenderdaten unterstützen das direkte Schreiben ohne Formatangabe. Heute mache ich mit diesen unformatierten Kalenderdaten weiter. Die folgende Tabelle zeigt das Standardausgabeformat von Kalenderdaten.

// createCalendar.cpp

#include <chrono>
#include <iostream>
 
int main() {

    std::cout << '\n';

    using namespace std::chrono_literals; 

    using std::chrono::last;

    using std::chrono::year;
    using std::chrono::month;
    using std::chrono::day;

    using std::chrono::year_month;
    using std::chrono::year_month_day;
    using std::chrono::year_month_day_last;
    using std::chrono::year_month_weekday;
    using std::chrono::year_month_weekday_last;
    using std::chrono::month_weekday;
    using std::chrono::month_weekday_last;
    using std::chrono::month_day;
    using std::chrono::month_day_last;
    using std::chrono::weekday_last;
    using std::chrono::weekday;

    using std::chrono::January;
    using std::chrono::February;
    using std::chrono::June;
    using std::chrono::March;
    using std::chrono::October;

    using std::chrono::Monday;
    using std::chrono::Thursday;
    using std::chrono::Sunday;

    constexpr auto yearMonthDay{year(1940)/month(6)/day(26)};  // (1)
    std::cout << yearMonthDay << " ";
    std::cout << year_month_day(1940y, June, 26d) << '\n';     // (2)

    std::cout << '\n';

    constexpr auto yearMonthDayLast{year(2010)/March/last};    // (3)
    std::cout << yearMonthDayLast << " ";
    std::cout << year_month_day_last(2010y, month_day_last(month(3))) << '\n';

    constexpr auto
      yearMonthWeekday{year(2020)/March/Thursday[2]};          // (4)
    std::cout << yearMonthWeekday << " ";
    std::cout << year_month_weekday(2020y, month(March), Thursday[2]) << '\n';

    constexpr auto 
      yearMonthWeekdayLast{year(2010)/March/Monday[last]};     //(5)
    std::cout << yearMonthWeekdayLast << " ";
    std::cout << year_month_weekday_last(2010y, month(March), weekday_last(Monday));

    std::cout << "\n\n";

    constexpr auto day_{day(19)};     // (6)         
    std::cout << day_  << " ";
    std::cout << day(19) << '\n';

    constexpr auto month_{month(1)};  // (7)     
    std::cout << month_  << " ";
    std::cout << month(1) << '\n';

    constexpr auto year_{year(1988)}; // (8)    
    std::cout << year_  << " ";
    std::cout << year(1988) << '\n';

    constexpr auto weekday_{weekday(5)};
    std::cout << weekday_  << " ";
    std::cout << weekday(5) << '\n';
 
    constexpr auto yearMonth{year(1988)/1};
    std::cout << yearMonth  << " ";
    std::cout << year_month(year(1988), January) << '\n';
 
    constexpr auto monthDay{10/day(22)};
    std::cout << monthDay <<  " ";
    std::cout << month_day(October, day(22)) << '\n';

    constexpr auto monthDayLast{June/last};
    std::cout << monthDayLast << " ";
    std::cout << month_day_last(month(6)) << '\n';
 
    constexpr auto monthWeekday{2/Monday[3]};
    std::cout << monthWeekday << " ";
    std::cout << month_weekday(February, Monday[3]) << '\n';
 
    constexpr auto monthWeekDayLast{June/Sunday[last]};
    std::cout << monthWeekDayLast << " ";
    std::cout << month_weekday_last(June, weekday_last(Sunday)) << '\n';

    std::cout << '\n';

}

Hier ist die Ausgabe des Programms:

Die folgende Tabelle zeigt die Formatangaben, einschließlich einer kurzen Beschreibung und eines Beispiels. Die vollständige Beschreibung findet sich auf der Seite cppreference.com/chrono/parse.

Das folgende Programm verwendet die Spezifizierer für die Uhrzeit und das Kalenderdatum.

// formattedOutputChrono.cpp

#include <chrono>
#include <iostream>
#include <thread>

int main() {

    std::cout << '\n';

    using namespace std::literals;

    auto start = std::chrono::steady_clock::now();   // (1)
    std::this_thread::sleep_for(33ms);
    auto end = std::chrono::steady_clock::now();     // (2)
    std::cout << std::format("The job took {} seconds\n", end - start);
    std::cout << std::format("The job took {:%S} seconds\n", end - start);

    std::cout << '\n';

    auto now = std::chrono::system_clock::now();    // (3)  
    std::cout << "now: " << now << '\n';
    std::cout << "Specifier {:%c}: " << std::format("{:%c}\n", now);
    std::cout << "Specifier {:%x}: " << std::format("{:%x}\n", now);
    std::cout << "Specifier {:%F}: " << std::format("{:%F}\n", now);
    std::cout << "Specifier {:%D}: " << std::format("{:%D}\n", now);
    std::cout << "Specifier {:%Y}: " << std::format("{:%Y}\n", now);
    std::cout << "Specifier {:%y}: " << std::format("{:%y}\n", now);
    std::cout << "Specifier {:%b}: " << std::format("{:%b}\n", now);
    std::cout << "Specifier {:%B}: " << std::format("{:%B}\n", now);
    std::cout << "Specifier {:%m}: " << std::format("{:%m}\n", now);
    std::cout << "Specifier {:%W}: " << std::format("{:%W}\n", now);
    std::cout << "Specifier {:%U}: " << std::format("{:%U}\n", now);
    std::cout << "Specifier {:%a}: " << std::format("{:%a}\n", now);
    std::cout << "Specifier {:%A}: " << std::format("{:%A}\n", now);
    std::cout << "Specifier {:%w}: " << std::format("{:%w}\n", now);
    std::cout << "Specifier {:%u}: " << std::format("{:%u}\n", now);
    std::cout << "Specifier {:%e}: " << std::format("{:%e}\n", now);
    std::cout << "Specifier {:%d}: " << std::format("{:%d}\n", now);

    std::cout << '\n';

}

Der Aufruf std::chrono::steady_clock::now() (1 und 2) bestimmt die aktuelle Zeit. Man sollte die std::chrono::steady_clock für Messungen verwenden, da diese Uhr monoton ist und nicht angepasst werden kann, wie beispielsweise std::chrono::system_clock (3).

Im nächsten Teil geht es um den Formatspezifizierer für formatierte Eingaben.

(rme)