Alles zu seiner Zeit

Jede Kultur hat ihre Eigenarten was die Angabe von Zeiten angibt. Mal kommt der Tag vor dem Monat, mal danach. Mal wird mit Punkten getrennt, mal mit Schrägstrichen, mal mit Bindestrichen. Namen unterscheiden sich sowieso von Landessprache zu Landessprache. Klingt nach einem perfekten Einsatzzweck von std::locale und einer passenden Facette.

Video

Quellcode

#include <iostream>
#include <locale>
#include <ctime>
#include <iomanip>

int main()
{
    auto now = std::time(nullptr);
    
    std::cout.imbue(std::locale("en_US.UTF-8"));
    std::cout << std::put_time(std::localtime(&now), "%c") << std::endl;
    std::cout << std::put_time(std::localtime(&now), "%X") << std::endl;

    std::cout.imbue(std::locale("de_DE.UTF-8"));
    std::cout << std::put_time(std::localtime(&now), "%c") << std::endl;
    std::cout << std::put_time(std::localtime(&now), "%X") << std::endl;
}

Erklärung

Im Beispiel wird die aktuelle Uhrzeit einmal nach US-amerikanischen und einmal nach deutschen Regeln ausgegeben. Zu diesem Zweck wird wie üblich die passende Locale an den Stream gebunden. Diese wird von std::put_time verwendet, um eine Uhrzeit zu formatieren.

std::put_time liefert einen unspezifizierten Rückgabetyp, der, wenn er auf einem std::ostream (oder wostream) ausgegeben wird, die passende Facette zur Ausgabe eines Datums laden soll, das Datum darüber formatieren und dann das Ergebnis auf dem Outputstream ausgeben soll. Es wird also nicht spezifiziert, wie das alles genau zu funktionieren hat und welche Typen involviert sind, sondern nur die letztendliche Wirkung spielt eine Rolle.

Die Templatefunktion übernimmt zwei Parameter: einmal die Uhrzeit als std::tm* (eine Struktur, in der die Uhrzeit nach ihren Einzelbestandteilen aufgedröselt ist) und einen Formatstring, der angibt, welche Teile der Uhrzeit auszugeben sind. Da die Funktion std::time in unserem Beispiel die Uhrzeit als Sekunden seit Kalenderbeginn zurückliefert, muss die passende Struktur erst noch mittels std::localtime erzeugt werden. Der Formatstring wird hier in zwei Varianten demonstriert: einerseits %c, die komplette Uhrzeit einschließlich Datum in einer länderspezifischen Darstellung und andererseits %X, nur die eigentliche Uhrzeit in länderspezifischer Darstellung. In beiden Fällen orientieren sich die Darstellung an der gesetzten Locale: Tages- und Monatsnamen sind in Landessprache, die Zeitdarstellung nach AM/PM oder 24-h-Darstellung passt.