Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <ctime>
- #include <cstdio>
- #include <sstream>
- #include <stdexcept>
- #include <limits>
- using namespace std;
- #define JAN "January"
- #define FEB "February"
- #define MAR "March"
- #define APR "April"
- #define MAY "May"
- #define JUN "June"
- #define JUL "July"
- #define AUG "August"
- #define SEP "September"
- #define OCT "October"
- #define NOV "November"
- #define DEC "December"
- #define SUN "Sun"
- #define MON "Mon"
- #define TUE "Tue"
- #define WED "Wed"
- #define THU "Thu"
- #define FRI "Fri"
- #define SAT "Sat"
- enum Month
- {
- Jan = 1,
- Feb,
- Mar,
- Apr,
- May,
- Jun,
- Jul,
- Aug,
- Sep,
- Oct,
- Nov,
- Dec
- };
- enum Day
- {
- Sun = 0,
- Mon,
- Tue,
- Wed,
- Thu,
- Fri,
- Sat
- };
- class Date
- {
- public:
- class Invalid : public runtime_error
- {
- public:
- Invalid() : runtime_error("Invalid date") {}
- };
- Date() : y(2001), m(Jan), d(1), days_in_month(31) {}
- Date(int yy, Month mm, int dd) : y(yy), m(mm), d(dd)
- {
- if (!is_valid(yy, mm, dd))
- {
- throw Invalid();
- }
- }
- int day() const { return d; }
- Month month() const { return m; }
- int year() const { return y; }
- int days() const { return days_in_month; }
- void add_day();
- void add_month();
- void add_year(int n);
- private:
- int y;
- Month m;
- int d;
- int days_in_month;
- bool is_valid(int y, Month m, int d);
- bool leapyear(int y)
- {
- return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
- }
- };
- bool Date::is_valid(int y, Month m, int d)
- {
- if (y < 1583)
- return false; // gregorian start
- if (d < 0)
- return false;
- if (m < Jan || Dec < m)
- return false;
- days_in_month = 31;
- switch (m)
- {
- case Feb:
- days_in_month = (leapyear(y)) ? 29 : 28;
- break;
- case Apr:
- case Jun:
- case Sep:
- case Nov:
- days_in_month = 30;
- break;
- }
- if (days_in_month < d)
- return false;
- return true;
- }
- void Date::add_day()
- {
- d++;
- if (d > days_in_month)
- {
- d = 1;
- add_month();
- }
- }
- void Date::add_month()
- {
- if (m == Dec)
- {
- m = Jan;
- add_year(1);
- }
- else if (m == Jan && d == 29 && !leapyear(y))
- {
- m = (Month)((int)m + 1);
- d = 28;
- }
- else
- {
- m = (Month)((int)m + 1);
- }
- if (!is_valid(y, m, d))
- {
- throw Invalid();
- }
- }
- void Date::add_year(int n)
- {
- if (m == Feb && d == 29 && !leapyear(y + n))
- {
- m = Mar;
- d = 1;
- }
- y += n;
- }
- tm makeTM(Date date)
- {
- tm get_tm = {};
- int d = date.day();
- int m = (int)date.month();
- int y = date.year();
- get_tm.tm_year = y - 1900;
- get_tm.tm_mon = m - 1;
- get_tm.tm_mday = d;
- if (mktime(&get_tm) == -1) {
- cerr << "Error: Invalid date" << endl;
- exit(1);
- }
- return get_tm;
- }
- static int stoi(string &s)
- {
- int i;
- istringstream(s) >> i;
- if (istringstream(s).fail()) {
- cerr << "Error: Invalid string to int conversion" << endl;
- exit(1);
- }
- return i;
- }
- int getDayOfWeek(const Date date)
- {
- tm get_day = makeTM(date);
- return get_day.tm_wday;
- }
- string printMonth(Date &d)
- {
- switch (d.month())
- {
- case Jan: return JAN;
- case Feb: return FEB;
- case Mar: return MAR;
- case Apr: return APR;
- case May: return MAY;
- case Jun: return JUN;
- case Jul: return JUL;
- case Aug: return AUG;
- case Sep: return SEP;
- case Oct: return OCT;
- case Nov: return NOV;
- case Dec: return DEC;
- default: return "mmm";
- }
- }
- void printHeader(const Date date)
- {
- cout << "==========" << endl;
- tm title = makeTM(date);
- cout << asctime(&title);
- cout << "==========" << endl;
- printf("|");
- printf("%-3s|", SUN);
- printf("%-3s|", MON);
- printf("%-3s|", TUE);
- printf("%-3s|", WED);
- printf("%-3s|", THU);
- printf("%-3s|", FRI);
- printf("%-3s|", SAT);
- printf("\n\n");
- }
- void printWeek(Date date)
- {
- Date begin(date.year(), date.month(), 1);
- int first_day = getDayOfWeek(begin);
- Day day = (Day)((int)first_day);
- printf("|");
- for (int i = 0; i < first_day; ++i)
- {
- printf("%-3s|", "X");
- }
- for (int i = 0; i < date.days(); ++i)
- {
- if (i + 1 == date.day())
- {
- printf("%-3s|", "_");
- }
- else
- {
- printf("%-3i|", begin.day());
- }
- switch (day)
- {
- case Sun: day = Mon; break;
- case Mon: day = Tue; break;
- case Tue: day = Wed; break;
- case Wed: day = Thu; break;
- case Thu: day = Fri; break;
- case Fri: day = Sat; break;
- case Sat:
- day = Sun;
- printf("\n|");
- break;
- }
- begin.add_day();
- }
- Date finish(date.year(), date.month(), date.days());
- int zero_sunday = 6;
- int end = zero_sunday - getDayOfWeek(finish);
- for (int i = 0; i < end; ++i)
- {
- printf("%-3s|", "X");
- }
- }
- int getValidInput(const string &prompt, int min, int max)
- {
- int value;
- int attempts = 0;
- while (attempts < 3)
- {
- cout << prompt;
- string input;
- getline(cin, input);
- if (input.empty())
- {
- cout << "Input cannot be empty. Please try again." << endl;
- attempts++;
- continue;
- }
- istringstream iss(input);
- if (!(iss >> value) || value < min || value > max)
- {
- cout << "Invalid input. Please try again." << endl;
- attempts++;
- }
- else
- {
- return value;
- }
- }
- cout << "You have entered invalid numbers consecutively three times. The application will now close after pressing Enter." << endl;
- cin.get(); // Wait for the user to press Enter
- exit(1);
- }
- int main()
- {
- int year = getValidInput("Enter the year (1583-9999): ", 1583, 9999);
- int month = getValidInput("Enter the month (1-12): ", 1, 12);
- int day = getValidInput("Enter the day (1-31): ", 1, 31);
- try {
- Date date(year, (Month)month, day);
- printHeader(date);
- printWeek(date);
- } catch (const Date::Invalid &e) {
- cerr << "Error: " << e.what() << endl;
- return 1;
- } catch (const exception &e) {
- cerr << "Error: " << e.what() << endl;
- return 1;
- }
- cout << "\n\nPress Enter to continue...";
- cin.get(); // Wait for the user to press Enter
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment