////
//// toordinal.cc
////
#include <iostream>
const int DAYS_IN_MONTH[] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int DAYS_BEFORE_MONTH[] = {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
/// year -> true if leap year, else false.
bool
isLeap(const int year)
{
return (year % 4 == 0) && ((year % 100 != 0) || (year % 400) == 0);
}
/// year, month -> number of days in that month in that year.
/// month must be in 1..12
int
daysInMonth(const int year, const int month)
{
if ((month == 2) && isLeap(year))
return 29;
return DAYS_IN_MONTH[month];
}
/// year -> number of days before January 1st of year.
int
daysBeforeYear(const int year)
{
const int y = year - 1;
return y*365 + y/4 - y/100 + y/400;
}
/// year, month -> number of days in year preceding first day of month.
/// month must be in 1..12
int
daysBeforeMonth(const int year, const int month)
{
return DAYS_BEFORE_MONTH[month] + ((month > 2 && isLeap(year)) ? 1 : 0);
}
/// year, month, day -> ordinal, considering 01-Jan-0001 as day 1.
/// year must be greater than 1
/// month must be in 1..12
/// day must be in 1..DAYS_IN_MONTH
int
ymd2ord(const int year, const int month, const int day)
{
return (daysBeforeYear(year) + daysBeforeMonth(year, month) + day);
}
/// Return proleptic Gregorian ordinal for the year, month and day.
/// January 1 of year 1 is day 1. Only the year, month and day values
/// contribute to the result.
int
toordinal(const int year, const int month, const int day)
{
return ymd2ord(year, month, day);
}
int main()
{
int year, month, day;
std::cout << "Enter year: ";
std::cin >> year;
std::cout << "Enter month: ";
std::cin >> month;
std::cout << "Enter day: ";
std::cin >> day;
std::cout << year << "-" << month << "-" << day << ": "
<< toordinal(year, month, day) << std::endl;
}