https://www.timeanddate.com/date/weekday.html berechnet verschiedene Fakten zu einem Tag des Jahres, zum Beispiel:
Wie können diese Zahlen bei einem beliebigen Datum mit der C ++ 20-Chronospezifikation berechnet werden ?
https://www.timeanddate.com/date/weekday.html berechnet verschiedene Fakten zu einem Tag des Jahres, zum Beispiel:
Wie können diese Zahlen bei einem beliebigen Datum mit der C ++ 20-Chronospezifikation berechnet werden ?
Antworten:
Dies ist mit der C ++ 20 Chrono-Spezifikation bemerkenswert einfach . Unten zeige ich eine Funktion, die ein beliebiges Datum eingibt und diese Informationen an druckt
cout
. Obwohl zum Zeitpunkt dieses Schreibens die C ++ 20-Chronospezifikation noch nicht ausgeliefert wurde, wird sie durch eine kostenlose Open-Source-Bibliothek angenähert . Sie können also heute damit experimentieren und es sogar in Versandanwendungen aufnehmen, solange Sie C ++ 11 oder höher verwenden.Diese Antwort hat die Form einer Funktion:
sys_days
ist eine Tagespräzisiontime_point
in dersystem_clock
Familie. Das heißt, es ist einfach eine Anzahl von Tagen seit 1970-01-01 00:00:00 UTC. Der Typaliassys_days
ist neu in C ++ 20, aber der zugrunde liegende Typ ist seit C ++ 11 (time_point<system_clock, duration<int, ratio<86400>>>
) verfügbar . Wenn Sie die Open-Source-Vorschau-Bibliothek C ++ 20 verwenden ,sys_days
ist innamespace date
.Der folgende Code setzt funktionslokal voraus:
Ausführlichkeit zu reduzieren. Wenn Sie mit der Open-Source-Vorschau-Bibliothek C ++ 20 experimentieren , nehmen Sie außerdem Folgendes an:
Überschrift
Die ersten beiden Zeilen auszugeben ist einfach:
Nehmen Sie einfach das Datum
sd
und verwenden Sie esformat
mit den bekanntenstrftime
/put_time
Flags, um das Datum und den Text auszudrucken. Die Open-Source-Vorschau-Bibliothek C ++ 20 hat die fmt-Bibliothek noch nicht integriert und verwendet daher die leicht geänderte Formatzeichenfolge"%d %B %Y is a %A\n"
.Dies gibt (zum Beispiel) Folgendes aus:
Gemeinsame Zwischenergebnisse einmal berechnet
Dieser Abschnitt der Funktion wird zuletzt geschrieben, da man noch nicht weiß, welche Berechnungen mehrmals benötigt werden. Aber sobald Sie es wissen, können Sie sie wie folgt berechnen:
Wir benötigen die Jahres- und Monatsfelder von
sd
und denweekday
(Wochentag). Es ist effizient, sie auf diese Weise ein für alle Mal zu berechnen. Wir werden auch (mehrmals) den ersten und den letzten Tag des laufenden Jahres benötigen. Es ist schwer , an diesem Punkt zu sagen, aber es ist effizient diese Werte als Typ speichernsys_days
als ihre spätere Verwendung nur mit Tag orientierte Arithmetik ist , diesys_days
ist sehr an (Subnanosekundenbereich Geschwindigkeiten) effizient.Fakt 1: Anzahl der Tage des Jahres und Anzahl der verbleibenden Tage im Jahr
Dies druckt die Tagesnummer des Jahres aus, wobei der 1. Januar der 1. Tag ist, und druckt dann auch die Anzahl der verbleibenden Tage im Jahr aus, ohne Berücksichtigung
sd
. Die Berechnung dazu ist trivial. Durch Teilen jedes Ergebnisses durchdays{1}
können Sie die Anzahl der Tage indn
unddl
in einen ganzzahligen Typ für Formatierungszwecke extrahieren .Fakt 2: Anzahl dieser Wochentage und Gesamtzahl der Wochentage im Jahr
wd
ist der Wochentag (Montag bis Sonntag), der oben in diesem Artikel berechnet wird. Um diese Berechnung durchzuführen, benötigen wir zuerst die Daten der ersten und letztenwd
im Jahry
.y/1/wd[1]
ist der erstewd
im Januar undy/12/wd[last]
der letztewd
im Dezember.Die Gesamtzahl der
wd
s im Jahr ist nur die Anzahl der Wochen zwischen diesen beiden Daten (plus 1). Der Unterausdrucklast_wd - first_wd
ist die Anzahl der Tage zwischen den beiden Daten. Das Teilen dieses Ergebnisses durch 1 Woche führt zu einem integralen Typ, der die Anzahl der Wochen zwischen den beiden Daten enthält.Die Wochennummer wird auf die gleiche Weise wie die Gesamtzahl der Wochen angegeben, außer dass eine mit dem aktuellen Tag anstelle des letzten
wd
des Jahres beginnt :sd - first_wd
.Fakt 3: Anzahl dieser Wochentage und Gesamtzahl der Wochentage im Monat
Dies funktioniert genau wie Fakt 2, außer dass wir mit dem ersten und letzten
wd
s des Jahr-Monat-Paaresy/m
anstelle des gesamten Jahres beginnen.Fakt 4: Anzahl der Tage im Jahr
Der Code spricht so ziemlich für sich.
Fakt 5 Anzahl der Tage im Monat
Der Ausdruck
y/m/last
ist der letzte Tag des Jahr-Monat-Paaresy/m
und natürlichy/m/1
der erste Tag des Monats. Beide werden so konvertiert,sys_days
dass sie subtrahiert werden können, um die Anzahl der Tage zwischen ihnen zu erhalten. Addiere 1 für die 1-basierte Anzahl.Verwenden
info
kann wie folgt verwendet werden:oder so:
Hier ist eine Beispielausgabe:
Bearbeiten
Für diejenigen, die die "konventionelle Syntax" nicht mögen, gibt es eine vollständige "Konstruktorsyntax", die stattdessen verwendet werden kann.
Zum Beispiel:
kann ersetzt werden durch:
quelle
std::cout << "a*b = " << a*b << "; a^b = " << a^b << '\n';
(das glücklicherweise fast immer zur Kompilierungszeit abgefangen wird, aber dennoch ärgerlich ist). Daher wäre ich vorsichtig, wenn ich diesen neuen Missbrauch von Abteilungsbetreibern verwende.