C++ Basics: Validate Calendar Fields Before Counting Days
Check year_month_day::ok before converting a date into a day-based time point.
Prepare a scratch directory
Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable compiler and standard-library development headers, with g++ on PATH. You also need Bash, a text editor, and the mktemp, rm, and rmdir utilities. No third-party library is required.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as chrono-calendar-validation-demo.cpp:
#include <chrono>
#include <iostream>
int main()
{
using namespace std::chrono;
for (int number : {2024, 2025}) {
const year_month_day date{year{number}, month{2}, day{29}};
std::cout << number << "-02-29 valid: " << std::boolalpha << date.ok() << '\n';
if (date.ok()) {
const year_month_day next{sys_days{date} + days{1}};
std::cout << "Next day: " << int(next.year()) << '-'
<< unsigned(next.month()) << '-' << unsigned(next.day()) << '\n';
}
}
}Compile and run it. The program runs only after compilation succeeds:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic chrono-calendar-validation-demo.cpp -o chrono-calendar-validation-demo &&
./chrono-calendar-validation-demoObserved output:
2024-02-29 valid: true
Next day: 2024-3-1
2025-02-29 valid: falseRead the result
February 29 exists in 2024, and adding one day reaches March 1. The same fields are invalid in 2025, so the example skips conversion and arithmetic for that date. Constructing the field-based value alone does not reject the invalid combination.
Apply it carefully
Call ok() before treating external date fields as a valid date. Day arithmetic belongs on sys_days, while adding months to a year_month_day can create an invalid date such as February 31. Recheck after calendar-field arithmetic. This example uses small in-range literals; validate wide external numbers before narrowing them into year, month, or day. Civil dates and day counts do not by themselves resolve a local time zone or daylight-saving transition.
The C++ working draft describes the relevant rules. This example builds in C++20 mode; the current working draft also documents later additions.
Clean up
Remove only the source and executable created here, then return to the starting directory:
rm -- chrono-calendar-validation-demo.cpp chrono-calendar-validation-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.