The Next Date
National Olympiad — Municipal round (2023 season)
Submission name: date.cpp
Problem summary
Given a valid Gregorian date, output the date of the following day. A year is leap if divisible by 400, or divisible by 4 but not by 100.
Input
Day D, month M and year Y.
Output
The next day, month and year, separated by spaces.
Constraints
1900 ≤ Y ≤ 2100; the input date is valid.
Worked example
An independently prepared example for this explanation.
Input
28 2 2005
Output
1 3 2005
Solution analysis
- Store the ordinary month lengths in an array. If the year is leap, change February from 28 to 29 days.
- Increment the day. If it exceeds the current month length, set it to 1 and increment the month. If the month becomes 13, set it to 1 and increment the year.
- For 28 February 2005, the year is not leap and February ends on day 28, so the next date is 1 March 2005. By contrast, 28 February 2000 is followed by 29 February because 2000 is divisible by 400.
Why it works
Within a month, incrementing the day gives the following date. Only the day after the month’s final day requires moving to the next month, and only December requires moving to the next year. The correctly adjusted February length makes these cases valid for both ordinary and leap years.
Watch out. Years divisible by 100 are not leap unless divisible by 400. The output year may be 2101 after 31 December 2100.
Commented C++17 solution
An independently written complete program with standard headers.
#include <iostream>
using namespace std;
int main() {
int day, month, year;
cin >> day >> month >> year;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Century years need the additional divisibility-by-400 exception.
bool leap = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
if (leap) {
days[2] = 29;
}
day++;
if (day > days[month]) {
day = 1;
month++;
}
if (month > 12) {
month = 1;
year++;
}
cout << day << ' ' << month << ' ' << year << '\n';
}