Date Difference Calculation
Given two dates, calculate the number of days between them. By convention, if the two dates are identical, the answer is 1. Consecutive dates have a difference of 2 days.
A two-dimensional array stores the number of days in each month, with the second dimension distinguishing between common years and leap years:
int daysPerMonth[13][2] = {
{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}
};
Approach 1: Incremental Day Counting
Increment the start date by one day repeatedly until it matches the end date:
#include <cstdio>
#include <algorithm>
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
int main() {
int startDate, endDate;
int daysPerMonth[13][2] = {
{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}
};
while (scanf("%d %d", &startDate, &endDate) != EOF) {
if (startDate > endDate) {
std::swap(startDate, endDate);
}
int y1 = startDate / 10000, m1 = (startDate % 10000) / 100, d1 = startDate % 100;
int y2 = endDate / 10000, m2 = (endDate % 10000) / 100, d2 = endDate % 100;
int count = 1;
while (y1 != y2 || m1 != m2 || d1 != d2) {
d1++;
count++;
if (d1 > daysPerMonth[m1][isLeapYear(y1)]) {
d1 = 1;
m1++;
}
if (m1 > 12) {
m1 = 1;
y1++;
}
}
printf("%d\n", count);
}
return 0;
}
Approach 2: Year-Level Optimization
For better performance, advance year by year when the gap is large:
#include <cstdio>
#include <algorithm>
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
int main() {
int startDate, endDate;
int daysPerMonth[13][2] = {
{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}
};
while (scanf("%d %d", &startDate, &endDate) != EOF) {
if (startDate > endDate) {
std::swap(startDate, endDate);
}
int y1 = startDate / 10000, m1 = (startDate % 10000) / 100, d1 = startDate % 100;
int y2 = endDate / 10000, m2 = (endDate % 10000) / 100, d2 = endDate % 100;
int count = 1;
while (y2 - y1 > 1) {
if (isLeapYear(y1) && d1 <= 2) {
count += 366;
} else if (isLeapYear(y1 + 1) && d1 > 2) {
count += 366;
} else {
count += 365;
}
y1++;
}
while (y1 != y2 || m1 != m2 || d1 != d2) {
d1++;
count++;
if (d1 > daysPerMonth[m1][isLeapYear(y1)]) {
d1 = 1;
m1++;
}
if (m1 > 12) {
m1 = 1;
y1++;
}
}
printf("%d\n", count);
}
return 0;
}
Day of Week Calculation
Use the Kim Larsson formula to determine the day of the week for a given date.
Formula: w = (d + 1 + 2*m + 3*(m+1)/5 + y + y/4 - y/100 + y/400) % 7
Where w = 0 represents Sunday through w = 6 for Saturday.
Important: Treat January and February as months 13 and 14 of the preceding year.
#include <cstdio>
#include <cstring>
int calculateDayOfWeek(int year, int month, int day) {
if (month == 1 || month == 2) {
month += 12;
year--;
}
return (day + 1 + 2 * month + 3 * (month + 1) / 5 +
year + year / 4 - year / 100 + year / 400) % 7;
}
int main() {
const char* dayNames[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
const char* monthNames[] = {"", "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"};
int day, year;
char monthStr[20];
while (scanf("%d %s %d", &day, monthStr, &year) != EOF) {
int month = 1;
for (int i = 1; i <= 12; i++) {
if (strcmp(monthNames[i], monthStr) == 0) {
month = i;
break;
}
}
printf("%s\n", dayNames[calculateDayOfWeek(year, month, day)]);
}
return 0;
}
Extended: Day of Year to Week
To find the weekday for the nth day of a given year:
w = (d + y - 1 + (y-1)/4 - (y-1)/100 + (y-1)/400) % 7
Where w = 0 corresponds to Sunday.
Converting Day-of-Year to Calendar Date
Given a year and the nth day of that year, output the corresponding date:
#include <cstdio>
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
int main() {
int year, dayOfYear;
int daysPerMonth[13][2] = {
{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}
};
while (scanf("%d %d", &year, &dayOfYear) != EOF) {
int month = 1, day = 0;
int leapFlag = isLeapYear(year);
while (dayOfYear > daysPerMonth[month][leapFlag]) {
dayOfYear -= daysPerMonth[month][leapFlag];
month++;
}
day = dayOfYear;
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}
Next Day Calculation
Given a date, output the following date:
#include <cstdio>
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
int main() {
int testCases, year, month, day;
int daysPerMonth[13][2] = {
{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}
};
scanf("%d", &testCases);
while (testCases--) {
scanf("%d %d %d", &year, &month, &day);
day++;
if (day > daysPerMonth[month][isLeapYear(year)]) {
day = 1;
month++;
}
if (month > 12) {
month = 1;
year++;
}
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}
Date Accumulation
Add a specifeid number of days to a given date:
#include <cstdio>
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
int main() {
int testCases, year, month, day, daysToAdd;
int daysPerMonth[13][2] = {
{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
{30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}
};
scanf("%d", &testCases);
while (testCases--) {
scanf("%d %d %d %d", &year, &month, &day, &daysToAdd);
while (daysToAdd--) {
day++;
if (day > daysPerMonth[month][isLeapYear(year)]) {
day = 1;
month++;
}
if (month > 12) {
month = 1;
year++;
}
}
printf("%04d-%02d-%02d\n", year, month, day);
}
return 0;
}
Leap Year Detection
A year is a leap year if:
- Divisible by 4 but not by 100, OR
- Divisible by 400
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}