https://www.timeanddate.com/date/weekday.html yılın bir günü hakkında çeşitli gerçekleri hesaplar, örneğin:
Keyfi bir tarih verildiğinde, bu sayılar C ++ 20 krono spesifikasyonu ile nasıl hesaplanabilir ?
https://www.timeanddate.com/date/weekday.html yılın bir günü hakkında çeşitli gerçekleri hesaplar, örneğin:
Keyfi bir tarih verildiğinde, bu sayılar C ++ 20 krono spesifikasyonu ile nasıl hesaplanabilir ?
Yanıtlar:
Bu, C ++ 20 krono spesifikasyonu ile oldukça kolaydır . Aşağıda gelişigüzel bir tarih girip bu bilgiyi üzerine yazdıran bir işlevi gösteriyorum cout
. Bu yazının yazıldığı sırada, C ++ 20 krono spesifikasyonu henüz gönderilmese de, ücretsiz, açık kaynaklı bir kütüphane ile yaklaşıyor . Böylece bugün deneyebilir ve hatta C ++ 11 veya üstünü benimsediğiniz sürece nakliye uygulamalarına dahil edebilirsiniz.
Bu cevap bir işlev şeklinde olacaktır:
void info(std::chrono::sys_days sd);
sys_days
Günde hassasiyetli bir time_point
de system_clock
ailesi. Bu, 1970-01-01 00:00:00 UTC'den bu yana geçen gün sayısı anlamına gelir. Tür takma adı sys_days
C ++ 20 ile yenidir, ancak altta yatan tür C ++ 11 ( time_point<system_clock, duration<int, ratio<86400>>>
) 'den beri mevcuttur . Eğer kullanırsanız açık kaynak C ++ 20 önizleme kütüphanesi , sys_days
içindedir namespace date
.
Aşağıdaki kodda yerel işlev varsayılmaktadır:
using namespace std;
using namespace std::chrono;
ayrıntı düzeyini azaltmak için. Eğer deneme yapıyorsanız açık kaynak C ++ 20 önizleme kütüphanede , farz edin ki:
using namespace date;
Başlık
İlk iki satırı çıkarmak basittir:
cout << format("{:%d %B %Y is a %A}\n", sd)
<< "\nAdditional facts\n";
Tarihi alın sd
ve tarihi ve metni yazdırmak format
için tanıdık strftime
/ put_time
bayraklarla kullanın. Açık kaynak C ++ 20 önizleme kütüphanesi henüz entegre edilmemiştir fmt kütüphane ve benzeri biraz değişmiş biçim dizesi kullanır "%d %B %Y is a %A\n"
.
Bu çıktı (örneğin):
26 December 2019 is a Thursday
Additional facts
Bir kez hesaplanan ortak ara sonuçlar
Fonksiyonun bu bölümü en son yazılır, çünkü hangi hesaplamaların birden fazla kez gerekli olacağını henüz bilmiyoruz. Ancak bir kez bildiğinizde, bunları nasıl hesaplayacağınız aşağıda açıklanmıştır:
year_month_day ymd = sd;
auto y = ymd.year();
auto m = ymd.month();
weekday wd{sd};
sys_days NewYears = y/1/1;
sys_days LastDayOfYear = y/12/31;
Yıl ve ay alanlarına sd
ve weekday
(haftanın günü) ihtiyacımız olacak. Bunları bir kez ve herkes için bu şekilde hesaplamak etkilidir. Ayrıca bu yılın ilk ve son günlerine de (birden çok kez) ihtiyacımız olacak. Noktada söylemek zor, ama türü olarak bu değerleri depolamak için etkilidir sys_days
onların daha sonraki kullanım sadece gündüz odaklı aritmetik ile olduğu gibi sys_days
olduğu çok (alt nanosaniye hızlarında) de etkili.
Gerçek 1: yılın gün sayısı ve yılda kalan gün sayısı
auto dn = sd - NewYears + days{1};
auto dl = LastDayOfYear - sd;
cout << "* It is day number " << dn/days{1} << " of the year, "
<< dl/days{1} << " days left.\n";
Bu, 1 Ocak 1 gün olmak üzere yılın gün sayısını yazdırır ve daha sonra dahil olmayan yıl içinde kalan gün sayısını yazdırır sd
. Bunu yapmak için yapılan hesaplama önemsizdir. Her bir sonucu bölmek, biçimlendirme amacıyla days{1}
gün sayısını dn
ve dl
ayrılmaz bir türe ayırmanın bir yoludur .
Gerçek 2: Bu hafta içi gün sayısı ve yıl içindeki toplam hafta içi gün sayısı
sys_days first_wd = y/1/wd[1];
sys_days last_wd = y/12/wd[last];
auto total_wd = (last_wd - first_wd)/weeks{1} + 1;
auto n_wd = (sd - first_wd)/weeks{1} + 1;
cout << format("* It is {:%A} number ", wd) << n_wd << " out of "
<< total_wd << format(" in {:%Y}.\n}", y);
wd
bu makalenin en üstünde hesaplanan haftanın günüdür (Pazartesi-Pazar). Bu hesaplamayı yapabilmek için önce wd
yıl içindeki ilk ve son tarihlere ihtiyacımız var y
. y/1/wd[1]
ilk wd
Ocak ayında ve y/12/wd[last]
son bir wd
Aralık ayında.
Yıldaki toplam wd
s sayısı, bu iki tarih arasındaki hafta sayısıdır (artı 1). Alt ifade last_wd - first_wd
, iki tarih arasındaki gün sayısıdır. Bu sonucun 1 haftaya bölünmesi, iki tarih arasındaki hafta sayısını tutan ayrılmaz bir türle sonuçlanır.
Hafta numarasını yerine geçen akım gün biri başlar hariç toplam hafta sayısı ile aynı şekilde yapılır wd
yılın: sd - first_wd
.
Gerçek 3: Bu hafta içi gün sayısı ve aydaki toplam hafta içi gün sayısı
first_wd = y/m/wd[1];
last_wd = y/m/wd[last];
total_wd = (last_wd - first_wd)/weeks{1} + 1;
n_wd = (sd - first_wd)/weeks{1} + 1;
cout << format("* It is {:%A} number }", wd) << n_wd << " out of "
<< total_wd << format(" in {:%B %Y}.\n", y/m);
Gerçek 2 gibi çalışır, ancak wd
yıl boyunca çiftin ilk ve son s'si ile başlarız y/m
.
Gerçek 4: Yıl içindeki gün sayısı
auto total_days = LastDayOfYear - NewYears + days{1};
cout << format("* Year {:%Y} has ", y) << total_days/days{1} << " days.\n";
Kod hemen hemen kendisi için konuşur.
Gerçek 5 Aydaki gün sayısı
total_days = sys_days{y/m/last} - sys_days{y/m/1} + days{1};
cout << format("* {:%B %Y} has ", y/m) << total_days/days{1} << " days.\n";
İfade y/m/last
, yıl-ay çiftinin son günü y/m
ve elbette y/m/1
ayın ilk günüdür. Her ikisi de, sys_days
aralarındaki gün sayısını almak için çıkarılabilecek şekilde dönüştürülür . 1 tabanlı sayı için 1 ekleyin.
kullanım
info
şu şekilde kullanılabilir:
info(December/26/2019);
ya da bunun gibi:
info(floor<days>(system_clock::now()));
İşte örnek çıktı:
26 December 2019 is a Thursday
Additional facts
* It is day number 360 of the year, 5 days left.
* It is Thursday number 52 out of 52 in 2019.
* It is Thursday number 4 out of 4 in December 2019.
* Year 2019 has 365 days.
* December 2019 has 31 days.
Düzenle
"Geleneksel sözdizimine" düşkün olmayanlar için, bunun yerine kullanılabilecek eksiksiz bir "yapıcı sözdizimi" vardır.
Örneğin:
sys_days NewYears = y/1/1;
sys_days first_wd = y/1/wd[1];
sys_days last_wd = y/12/wd[last];
ile değiştirilebilir:
sys_days NewYears = year_month_day{y, month{1}, day{1}};
sys_days first_wd = year_month_weekday{y, month{1}, weekday_indexed{wd, 1}};
sys_days last_wd = year_month_weekday_last{y, month{12}, weekday_last{wd}};
std::cout << "a*b = " << a*b << "; a^b = " << a^b << '\n';
(ki, neyse ki, neredeyse her zaman derleme zamanında yakalanır, ancak yine de bir sıkıntıdır). Bu nedenle, bu yeni bölüm operatörünü kötüye kullanırken dikkatli olurum.