https://www.timeanddate.com/date/weekday.html 은 연중 무휴에 대한 다양한 사실을 계산합니다. 예를 들면 다음과 같습니다.
임의의 날짜가 주어지면 C ++ 20 크로노 사양으로 이러한 숫자를 어떻게 계산할 수 있습니까?
https://www.timeanddate.com/date/weekday.html 은 연중 무휴에 대한 다양한 사실을 계산합니다. 예를 들면 다음과 같습니다.
임의의 날짜가 주어지면 C ++ 20 크로노 사양으로 이러한 숫자를 어떻게 계산할 수 있습니까?
답변:
이것은 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
사용 하여 날짜와 텍스트를 인쇄하십시오. 오픈 소스 C ++ 20 미리보기 라이브러리는 아직 통합되지 않은 FMT 라이브러리를 , 그래서 약간 변경 형식 문자열을 사용합니다 .format
strftime
put_time
"%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 일이 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
. 1 월 y/1/wd[1]
의 첫 번째 이며 12 월 의 마지막 입니다.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);
이것은 wd
연도 y/m
대신 첫 달 과 마지막 달로 시작한다는 점을 제외하고는 사실 2와 동일하게 작동합니다 .
사실 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';
거의 다를 수 있습니다 (다행히 컴파일 타임에 거의 항상 잡히지 만 여전히 성가심입니다). 따라서이 새로운 부서 운영자 남용을 사용할 때는주의해야합니다.