Zeit in C++20: Chrono I/O

Chrono I/O umfasst das Lesen und Schreiben von Chronotypen. Die Datentypen unterstützen unformatiertes und formatiertes Schreiben mit der neuen Bibliothek.​

In Pocket speichern vorlesen Druckansicht 2 Kommentare lesen

(Bild: Min C. Chiu/Shutterstock.com)

Lesezeit: 2 Min.
Von
  • Rainer Grimm
Inhaltsverzeichnis
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++.

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

Die meisten Datentypen, wie z.B. Zeitdauer, Zeitpunkte und Kalenderdaten, können ohne Formatangabe direkt geschrieben werden.

Die nachfolgende Tabelle zeigt das Standardausgabeformat. Beginnen wir mit den Zeitdauern.

Zeitdauern

Das Programm zeigt Werte für jede Zeitdauer an.

// timeDurationsOutput.cpp

#include <chrono>
#include <iostream>

int main() {

    std::cout << '\n';

    using namespace std::chrono_literals;

    std::cout << "5ns: " << 5ns << '\n';
    std::cout << "std::chrono::nanoseconds(5): " 
              << std::chrono::nanoseconds(5) << '\n';

    std::cout << '\n';

    std::cout << "5ms: " << 5ms << '\n';
    std::cout << "std::chrono::microseconds(5): " 
              << std::chrono::microseconds(5) << '\n';

    std::cout << '\n';

    std::cout << "5us: " << 5us << '\n';
    std::cout << "std::chrono::milliseconds(5): " 
              << std::chrono::milliseconds(5) << '\n';

    std::cout << '\n';

    std::cout << "5s: " << 5s << '\n';
    std::cout << "std::chrono::seconds(5): " << std::chrono::seconds(5) << '\n';

    std::cout << '\n';

    std::cout << "5min: " << 5min << '\n';
    std::cout << "std::chrono::minutes(5): " << std::chrono::minutes(5) << '\n';

    std::cout << '\n';

    std::cout << "5h: " << 5h << '\n';
    std::cout << "std::chrono::hours(5): " << std::chrono::hours(5) << '\n';

    std::cout << '\n';

    std::cout << "std::chrono::days(5): " << std::chrono::days(5) << '\n';

    std::cout << '\n';

    std::cout << "std::chrono::weeks(5): " << std::chrono::weeks(5) << '\n';

    std::cout << '\n';

    std::cout << "std::chrono::months(5): " << std::chrono::months(5) << '\n';

    std::cout << '\n';

    std::cout << "std::chrono::years(5): " << std::chrono::years(5) << '\n';  

    std::cout << '\n';

}

Die natürlichen Zahlen in den eckigen Klammern von std::chrono::weeks, std::chrono::months und std::chrono::years stehen für die Anzahl der Sekunden.

Zeitpunkte

Verwendet man die statische Mitgliedsfunktion now der C++20-Uhren, erhält man das Datum und die Uhrzeit in dem im Listing gezeigten Format:

year-month-day hours:minutes:seconds

Das folgende Programm gibt die aktuelle Zeit mit allen C++20-Uhren an.

// timePointsOutput.cpp

#include <chrono>
#include <iostream>

int main() {

    std::cout << '\n';

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

    auto nowSteadyClock = std::chrono::steady_clock::now();
    // std::cout << "nowSteadyClock: " << nowSteadyClock << '\n';    ERROR
 
    auto nowFileClock = std::chrono::file_clock::now();
    std::cout << "nowFileClock:   " << nowFileClock << '\n';

    auto nowGPSClock = std::chrono::gps_clock::now();
    std::cout << "nowGPSClock:    " << nowGPSClock << '\n';

    // auto nowlocal_tClock = std::chrono::local_t::now();           ERROR

    auto nowTAIClock = std::chrono::tai_clock::now();
    std::cout << "nowTAIClock:    " << nowTAIClock << '\n';

    auto nowUTCClock = std::chrono::utc_clock::now();
    std::cout << "nowUTCClock:    " << nowUTCClock << '\n';

    std::cout << '\n';

}

Das Programm zeigt zwei interessante Fakten. Erstens kann die aktuelle Zeit, die von der std::chrono::steady_clock::now() gegeben wird, nicht angezeigt werden. Zweitens hat die Pseudo-Uhr std::chrono::local_t keine statische Mitgliedsfunktion now().

Die GPS-Zeit ist der UTC-Zeit um 18 Sekunden voraus. Die TAI-Zeit liegt 37 Sekunden vor der UTC-Zeit und 19 Sekunden vor der GPS-Zeit.

Dank der C++17-Funktion std::chrono::floor kann man den Zeitpunkt in verschiedenen Granularitäten darstellen. In diesem Fall muss der Zeitpunkt vom Datentyp std::chrono::local_time sein.

// timePointsOutputGranularity.cpp

#include <chrono>
#include <iostream>

int main() {

    std::cout << '\n';

    auto now = std::chrono::system_clock::now();
    
    auto zonedTime = std::chrono::zoned_time(std::chrono::current_zone(), now); 
    auto localTime = zonedTime.get_local_time();

    std::cout << "local_time:                                               " 
              << localTime << '\n';

    std::cout << "std::chrono::floor<std::chrono::microseconds>(localTime): " 
              << std::chrono::floor<std::chrono::microseconds>(localTime) << '\n'; 

    std::cout << "std::chrono::floor<std::chrono::milliseconds>(localTime): "
              << std::chrono::floor<std::chrono::milliseconds>(localTime) << '\n';

    std::cout << "std::chrono::floor<std::chrono::seconds>(localTime):      "
              << std::chrono::floor<std::chrono::seconds>(localTime) << '\n';
    
    std::cout << "std::chrono::floor<std::chrono::minutes>(localTime):      "
              << std::chrono::floor<std::chrono::minutes>(localTime) << '\n';

    std::cout << "std::chrono::floor<std::chrono::hours>(localTime):        " 
              << std::chrono::floor<std::chrono::hours>(localTime) << '\n';

    std::cout << "std::chrono::floor<std::chrono::days>(localTime):         "
              << std::chrono::floor<std::chrono::days>(localTime) << '\n';

    std::cout << "std::chrono::floor<std::chrono::weeks>(localTime):        "
              << std::chrono::floor<std::chrono::weeks>(localTime) << '\n';

    // std::cout << std::chrono::floor<std::chrono::months>(localTime) << '\n';    ERROR
    // std::cout << std::chrono::floor<std::chrono::years>(localTime) << '\n';     ERROR

    std::cout << '\n';

}

Das Programm gibt localTime in verschiedenen Genauigkeiten an, beginnend mit der Zeitdauer std::chrono::microseconds und endend mit std::chrono::weeks. Seltsamerweise können die Zeitdauern für std::chrono::months und std::chrono::years nicht angezeigt werden. Dieses Manko soll mit C++23 behoben werden.

Mein nächster Artikel beschreibt, wie sich zusätzlich auch Kalenderdaten unformatiert anzeigen lassen. (map)