https://www.timeanddate.com/date/weekday.html вычисляет различные факты о дне года, например:
Учитывая произвольную дату, как эти числа могут быть вычислены с хронологической спецификацией C ++ 20 ?
https://www.timeanddate.com/date/weekday.html вычисляет различные факты о дне года, например:
Учитывая произвольную дату, как эти числа могут быть вычислены с хронологической спецификацией C ++ 20 ?
Ответы:
Это очень просто с хронологической спецификацией C ++ 20 . Ниже я показываю функцию, которая вводит произвольную дату и печатает эту информацию
cout
. Хотя на момент написания этой статьи спецификация C ++ 20 chrono еще не поставлялась, она приближается к бесплатной библиотеке с открытым исходным кодом . Таким образом, вы можете поэкспериментировать с ним сегодня и даже включить его в поставку приложений, если вы используете C ++ 11 или более позднюю версию.Этот ответ примет форму функции:
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
.Код ниже предполагает локальную функцию:
уменьшить многословие. Если вы экспериментируете с библиотекой предварительного просмотра C ++ 20 с открытым исходным кодом , также предположите:
Heading
Вывести первые две строки просто:
Просто возьмите дату
sd
и используйтеformat
знакомыеstrftime
/put_time
флаги, чтобы распечатать дату и текст. C ++ 20 библиотеки просмотра с открытым исходным кодом еще не интегрировала библиотеку FMT , и поэтому использует слегка измененную строку формата"%d %B %Y is a %A\n"
.Это выведет (например):
Общие промежуточные результаты вычисляются один раз
Этот раздел функции написан последним, потому что еще не известно, какие вычисления понадобятся несколько раз. Но как только вы знаете, вот как их вычислить:
Нам понадобятся поля года и месяца
sd
, а такжеweekday
(день недели). Таким способом их можно вычислить раз и навсегда. Нам также понадобятся (несколько раз) первый и последний дни текущего года. Трудно сказать , в этот момент, но это эффективно хранить эти значения типа ,sys_days
как их последующее использование только с однодневной ориентированной арифметики , котораяsys_days
является очень эффективным при (скорости субнаносекундной).Факт 1: число дней в году и количество дней, оставшихся в году
Это печатает номер дня года, где 1 января - день 1, а затем также выводит количество дней, оставшихся в году, не включая
sd
. Вычисление, чтобы сделать это тривиально. Разделение каждого результатаdays{1}
- это способ извлечения количества дней вdn
иdl
для целочисленного типа в целях форматирования.Факт 2: номер этого дня недели и общее количество дней недели в году.
wd
день недели (с понедельника по воскресенье), вычисленный в начале этой статьи. Для выполнения этого вычисления нам сначала нужны даты первого и последнего числаwd
в годуy
.y/1/wd[1]
первыйwd
в январе иy/12/wd[last]
последнийwd
в декабре.Общее количество
wd
s в году - это количество недель между этими двумя датами (плюс 1). Подвыражениеlast_wd - first_wd
- это количество дней между двумя датами. Разделение этого результата на 1 неделю приводит к целочисленному типу, содержащему количество недель между двумя датами.Номер недели делается таким же образом , как общее число недель , за исключением одного начинается с текущим днем вместо последнего
wd
года:sd - first_wd
.Факт 3: номер этого дня недели и общее количество дней недели в месяце.
Это работает так же, как Факт 2, за исключением того, что мы начинаем с первого и последнего
wd
с пары год-месяцy/m
вместо всего года.Факт 4: количество дней в году
Код в значительной степени говорит сам за себя.
Факт 5 Количество дней в месяце
Выражение
y/m/last
является последним днем пары год-месяцy/m
и, конечно,y/m/1
первым днем месяца. Оба преобразуются вsys_days
так, что они могут быть вычтены, чтобы получить количество дней между ними. Добавьте 1 для подсчета на основе 1.использование
info
можно использовать так:или вот так:
Вот пример вывода:
редактировать
Для тех, кто не любит «обычный синтаксис», есть полный «синтаксис конструктора», который можно использовать вместо этого.
Например:
можно заменить на:
источник
std::cout << "a*b = " << a*b << "; a^b = " << a^b << '\n';
(которое, к счастью, почти всегда ловится во время компиляции, но все же вызывает раздражение). Так что я буду осторожен при использовании нового злоупотребления оператором подразделения.