https://www.timeanddate.com/date/weekday.html oblicza różne fakty dotyczące dnia roku, na przykład:
Biorąc pod uwagę dowolną datę, w jaki sposób można obliczyć te liczby ze specyfikacją chronografu C ++ 20 ?
https://www.timeanddate.com/date/weekday.html oblicza różne fakty dotyczące dnia roku, na przykład:
Biorąc pod uwagę dowolną datę, w jaki sposób można obliczyć te liczby ze specyfikacją chronografu C ++ 20 ?
Odpowiedzi:
Jest to niezwykle łatwe dzięki specyfikacji chronografu C ++ 20 . Poniżej pokazuję funkcję, która wprowadza dowolną datę i wypisuje tę informację na
cout
. Chociaż w chwili pisania tego tekstu specyfikacja chronografu C ++ 20 nie jest jeszcze dostępna, jest ona aproksymowana przez bezpłatną bibliotekę typu open source . Możesz więc eksperymentować z nim już dziś, a nawet uwzględnić go w aplikacjach wysyłkowych, o ile zastosujesz C ++ 11 lub nowszy.Ta odpowiedź przybierze postać funkcji:
sys_days
to precyzja dniatime_point
wsystem_clock
rodzinie. Oznacza to, że jest to po prostu liczba dni od 1970-01-01 00:00:00 UTC. Alias typusys_days
jest nowy w C ++ 20, ale typ podstawowy jest dostępny od C ++ 11 (time_point<system_clock, duration<int, ratio<86400>>>
). Jeśli używasz biblioteki podglądu C ++ 20 typu open source ,sys_days
jest wnamespace date
.Poniższy kod zakłada lokalną funkcję:
w celu zmniejszenia gadatliwości. Jeśli eksperymentujesz z biblioteką podglądu C ++ 20 typu open source , załóż również:
Nagłówek
Wyprowadzenie pierwszych dwóch wierszy jest proste:
Po prostu weź datę
sd
i użyjformat
ze znanymistrftime
/put_time
flagami, aby wydrukować datę i tekst. C ++ 20 podgląd biblioteki open-source nie został jeszcze zintegrowany z biblioteki FMT , a więc korzysta z lekko zmienioną ciąg formatu"%d %B %Y is a %A\n"
.Spowoduje to wyświetlenie (na przykład):
Wspólne wyniki pośrednie obliczane raz
Ta sekcja funkcji jest zapisywana jako ostatnia, ponieważ nie wiadomo jeszcze, jakie obliczenia będą potrzebne wiele razy. Ale kiedy już wiesz, oto jak je obliczyć:
Będziemy potrzebować pól roku i miesiąca
sd
orazweekday
(dnia tygodnia). Skuteczne jest obliczenie ich raz na zawsze w ten sposób. Będziemy także potrzebować (wiele razy) pierwszy i ostatni dzień bieżącego roku. Trudno w tym momencie powiedzieć, ale efektywne jest przechowywanie tych wartości jako typu,sys_days
ponieważ ich późniejsze użycie jest tylko z arytmetyką zorientowaną na dzień, którasys_days
jest bardzo wydajna przy (prędkościach poniżej nanosekundowych).Fakt 1: liczba dni w roku i liczba dni pozostałych w roku
Spowoduje to wydrukowanie numeru dnia roku, przy czym 1 stycznia jest dniem 1, a następnie wydrukowanie liczby dni pozostałych w roku, bez uwzględnienia
sd
. Obliczenia tego są trywialne. Podzielenie wyniku przez każdydays{1}
jest sposób wydobycia liczby dnidn
idl
w integralny typu dla celów formatowania.Fakt 2: Liczba dni tygodnia i całkowita liczba dni tygodnia w roku
wd
to dzień tygodnia (od poniedziałku do niedzieli) obliczony na początku tego artykułu. Aby wykonać to obliczenie, najpierw potrzebujemy daty pierwszego i ostatniegowd
rokuy
.y/1/wd[1]
jest pierwszywd
w styczniu, ay/12/wd[last]
ostatniwd
w grudniu.Całkowita liczba
wd
s w ciągu roku to tylko liczba tygodni między tymi dwiema datami (plus 1). Podwyrażenielast_wd - first_wd
to liczba dni między dwiema datami. Dzielenie tego wyniku przez 1 tydzień powoduje, że typem integralnym jest liczba tygodni między dwiema datami.Liczba tygodni odbywa się tak samo, jak w ogólnej liczbie tygodni wyjątkiem jednego startów z bieżącego dnia zamiast ostatniego
wd
roku:sd - first_wd
.Fakt 3: Liczba dni tygodnia i całkowita liczba dni tygodnia w miesiącu
Działa to tak, jak w Fact 2, tyle że zaczynamy od pierwszej i ostatniej
wd
pary pary rok-miesiący/m
zamiast przez cały rok.Fakt 4: Liczba dni w roku
Kod mówi sam za siebie.
Fakt 5 Liczba dni w miesiącu
Wyrażenie
y/m/last
to ostatni dzień pary rok-miesiący/m
i oczywiściey/m/1
pierwszy dzień miesiąca. Oba są konwertowane nasys_days
, aby można je było odjąć, aby uzyskać liczbę dni między nimi. Dodaj 1 dla liczby opartej na 1.Posługiwać się
info
można użyć w następujący sposób:lub tak:
Oto przykładowy wynik:
Edytować
Dla tych, którzy nie lubią „konwencjonalnej składni”, dostępna jest pełna „składnia konstruktora”.
Na przykład:
można zastąpić:
źródło
std::cout << "a*b = " << a*b << "; a^b = " << a^b << '\n';
(które na szczęście prawie zawsze jest łapane w czasie kompilacji, ale nadal jest uciążliwe). Byłbym więc ostrożny przy użyciu tego nowego nadużycia operatora oddziału.