https://www.timeanddate.com/date/weekday.htmlคำนวณข้อเท็จจริงต่าง ๆ เกี่ยวกับวันของปีตัวอย่างเช่น:
ให้วันที่โดยพลการตัวเลขเหล่านี้สามารถคำนวณได้ด้วยข้อกำหนดC ++ 20 chronoอย่างไร
https://www.timeanddate.com/date/weekday.htmlคำนวณข้อเท็จจริงต่าง ๆ เกี่ยวกับวันของปีตัวอย่างเช่น:
ให้วันที่โดยพลการตัวเลขเหล่านี้สามารถคำนวณได้ด้วยข้อกำหนดC ++ 20 chronoอย่างไร
คำตอบ:
นี้เป็นอย่างน่าทึ่งง่ายด้วยC ++ 20 สเปคโครโน cout
ด้านล่างนี้ผมแสดงฟังก์ชั่นซึ่งปัจจัยการผลิตวันโดยพลการและพิมพ์ข้อมูลนี้ไปยัง แม้ว่าในขณะที่เขียนนี้ที่สเปคโครโน C ++ 20ยังไม่ได้รับการจัดส่งสินค้าก็จะประมาณโดยฟรีห้องสมุดเปิดแหล่งที่มา ดังนั้นคุณสามารถทดลองกับมันได้ในวันนี้และรวมไว้ในแอปพลิเคชันการจัดส่งตราบใดที่คุณใช้ C ++ 11 หรือใหม่กว่า
คำตอบนี้จะอยู่ในรูปแบบของฟังก์ชั่น:
void info(std::chrono::sys_days sd);
sys_days
เป็นวันที่มีความแม่นยำtime_point
ในsystem_clock
ครอบครัว ซึ่งหมายความว่ามันเป็นเพียงการนับวันตั้งแต่ 1970-01-01 00:00:00 UTC นามแฝงประเภทsys_days
นั้นใหม่พร้อมด้วย C ++ 20 แต่ประเภทพื้นฐานมีให้บริการตั้งแต่ C ++ 11 ( time_point<system_clock, duration<int, ratio<86400>>>
) ถ้าคุณใช้โอเพนซอร์ส C ++ 20 ห้องสมุดภาพตัวอย่าง , อยู่ในsys_days
namespace date
รหัสด้านล่างจะถือว่าเป็นฟังก์ชันในเครื่อง:
using namespace std;
using namespace std::chrono;
เพื่อลดการฟุ่มเฟื่อย หากคุณกำลังทดลองกับไลบรารีตัวอย่าง C ++ 20 แบบโอเพ่นซอร์สให้ถือว่า:
using namespace date;
หัวเรื่อง
ในการแสดงผลสองบรรทัดแรกนั้นง่าย:
cout << format("{:%d %B %Y is a %A}\n", sd)
<< "\nAdditional facts\n";
เพียงใช้วันที่sd
และใช้งานformat
ร่วมกับstrftime
/ put_time
ธงที่คุ้นเคยเพื่อพิมพ์วันที่และข้อความ โอเพนซอร์ส C ++ 20 ห้องสมุดภาพตัวอย่างยังไม่รวมห้องสมุด fmt"%d %B %Y is a %A\n"
และเพื่อให้ใช้สตริงรูปแบบการเปลี่ยนแปลงเล็กน้อย
สิ่งนี้จะเอาท์พุต (ตัวอย่าง):
26 December 2019 is a Thursday
Additional facts
ผลลัพธ์กลางทั่วไปที่คำนวณได้หนึ่งครั้ง
ส่วนของฟังก์ชั่นนี้เขียนครั้งสุดท้ายเพราะยังไม่ทราบว่าการคำนวณจะต้องใช้หลายครั้ง แต่เมื่อคุณรู้แล้วนี่คือวิธีการคำนวณ:
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;
เราจะต้องการฟิลด์ปีและเดือนของsd
และweekday
(วันของสัปดาห์) มันมีประสิทธิภาพในการคำนวณพวกเขาครั้งเดียวและสำหรับทั้งหมดในลักษณะนี้ นอกจากนี้เรายังต้องการ (หลายครั้ง) ในวันแรกและวันสุดท้ายของปีปัจจุบัน มันยากที่จะบอก ณ จุดนี้ แต่มันมีประสิทธิภาพในการจัดเก็บค่าเหล่านี้เป็นประเภทsys_days
เนื่องจากการใช้งานครั้งต่อไปของพวกเขาจะใช้เฉพาะกับเลขคณิตแบบมุ่งเน้นรายวันซึ่งsys_days
มีประสิทธิภาพมากที่ (ความเร็วระดับนาโนวินาที)
ข้อเท็จจริง 1: จำนวนวันของปีและจำนวนวันที่เหลือในปี
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";
พิมพ์นี้ออกมาจำนวนวันของปีกับ 1 มกราคมเป็นวันที่ 1 sd
แล้วยังพิมพ์ออกมาจำนวนวันที่เหลือในปีนี้ไม่รวม การคำนวณเพื่อทำสิ่งนี้เป็นเรื่องเล็กน้อย การหารผลลัพธ์แต่ละรายการด้วยdays{1}
วิธีการแยกจำนวนวันในdn
และdl
เป็นประเภทอินทิกรัลสำหรับวัตถุประสงค์ในการจัดรูปแบบ
ข้อเท็จจริงที่ 2: จำนวนวันทำงานนี้และจำนวนวันทำงานทั้งหมดในปี
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
เป็นวันในสัปดาห์ (วันจันทร์ถึงวันอาทิตย์) คำนวณที่ด้านบนของบทความนี้ เพื่อดำเนินการคำนวณนี้ครั้งแรกที่เราต้องทราบวันแรกและสุดท้าย'ในปี wd
เป็นคนแรกในเดือนมกราคมและเป็นคนสุดท้ายในเดือนธันวาคมy
y/1/wd[1]
wd
y/12/wd[last]
wd
จำนวนทั้งหมดของwd
ปีเป็นเพียงจำนวนสัปดาห์ระหว่างสองวันนี้ (บวก 1) นิพจน์ย่อยlast_wd - first_wd
คือจำนวนวันระหว่างวันที่สองวัน การหารผลลัพธ์นี้ด้วย 1 สัปดาห์ส่งผลให้มีประเภทหนึ่งที่ถือจำนวนสัปดาห์ระหว่างวันที่สองวัน
จำนวนสัปดาห์จะทำแบบเดียวกับจำนวนรวมของสัปดาห์ยกเว้นหนึ่งเริ่มต้นด้วยวันที่ปัจจุบันแทนของสุดท้ายของปี:wd
sd - first_wd
ข้อเท็จจริงที่ 3: จำนวนวันทำงานนี้และจำนวนวันทำงานทั้งหมดในเดือน
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);
สิ่งนี้ทำงานได้เหมือน Fact 2 ยกเว้นว่าเราเริ่มต้นด้วยคู่แรกและคู่สุดท้ายwd
ของคู่เดือนปีy/m
แทนที่จะเป็นทั้งปี
ความจริง 4: จำนวนวันในปี
auto total_days = LastDayOfYear - NewYears + days{1};
cout << format("* Year {:%Y} has ", y) << total_days/days{1} << " days.\n";
รหัสสวยมากพูดสำหรับตัวเอง
ข้อเท็จจริง 5 จำนวนวันในเดือน
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";
การแสดงออกy/m/last
เป็นวันสุดท้ายของคู่เดือนปีy/m
และแน่นอนy/m/1
เป็นวันแรกของเดือน ทั้งสองถูกแปลงเป็นเพื่อsys_days
ให้สามารถลบออกเพื่อรับจำนวนวันระหว่างพวกเขา เพิ่ม 1 สำหรับการนับ 1 รายการ
ใช้
info
สามารถใช้ดังนี้:
info(December/26/2019);
หรือเช่นนี้
info(floor<days>(system_clock::now()));
นี่คือตัวอย่างเอาต์พุต:
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.
แก้ไข
สำหรับผู้ที่ไม่ชอบ "ไวยากรณ์ทั่วไป" จะมี "ผู้สร้างไวยากรณ์" ที่สามารถใช้แทนได้
ตัวอย่างเช่น:
sys_days NewYears = y/1/1;
sys_days first_wd = y/1/wd[1];
sys_days last_wd = y/12/wd[last];
สามารถถูกแทนที่ด้วย:
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';
(ซึ่งก็คือโชคดีที่เกือบทุกครั้งที่รวบรวมเวลา แต่ก็ยังเป็นเรื่องน่ารำคาญ) ดังนั้นฉันจึงต้องระมัดระวังเมื่อใช้การละเมิดผู้ปฏิบัติงานในแผนกใหม่นี้