Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ctime>
- #include <iostream>
- #include <string>
- using namespace std::literals;
- template <typename T>
- T read(const std::string& request)
- {
- auto except = std::cin.exceptions();
- try {
- std::cin.exceptions(std::ios::eofbit | std::ios::badbit);
- std::cout << request;
- T value;
- bool repeat = true;
- while (repeat) {
- repeat = false;
- std::cin >> value;
- if(!std::cin) {
- std::cout << "Invalid input\n";
- std::cin.clear();
- repeat = true;
- while(!isspace(std::cin.get()) && std::cin)
- ;
- }
- }
- std::cin.exceptions(except);
- return value;
- } catch(...) {
- std::cin.exceptions(except);
- throw;
- }
- }
- bool ask(const std::string& question)
- {
- std::cout << question << '\n';
- char c;
- do {
- c = static_cast<char>(tolower(read<char>("")));
- if(c != 'y' && c != 'n')
- std::cout << "Invalid answer. Only Y, y, N and n are allowed\n";
- } while(c != 'y' && c != 'n');
- return c == 'y';
- }
- namespace date
- {
- // ↓ January December ↓
- constexpr int month_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- constexpr int year_days = 365;
- struct date_diff
- {
- int year;
- int mon;
- int day;
- };
- date_diff operator-(const std::tm& lhs, const std::tm& rhs)
- {
- date_diff result {lhs.tm_year - rhs.tm_year,
- lhs.tm_mon - rhs.tm_mon ,
- lhs.tm_mday - rhs.tm_mday };
- if(result.day < 0) {
- result.day += month_days[rhs.tm_mon];
- --result.mon;
- }
- if(result.mon < 0) {
- result.mon += 12;
- --result.year;
- }
- return result;
- }
- std::tm get_current_date()
- {
- std::time_t now = std::time(nullptr);
- return *std::localtime(&now);
- }
- std::tm get_date()
- {
- std::tm result {0, 0, 0 ,0, 0, 0, 0, 0, 0};
- result.tm_year = read<int>("Enter year: " ) - 1900; //Epoch start
- result.tm_mon = read<int>("Enter month: ") - 1; //Internal representation fix
- result.tm_mday = read<int>("Enter day: " );
- std::mktime(&result);
- return result;
- }
- std::string date_to_string(const std::tm& date)
- {
- constexpr std::size_t buff_size = 128;
- char buff[buff_size];
- if(strftime(buff, buff_size - 1, "%d/%m/%Y", &date) == 0)
- return "";
- return buff;
- }
- void agecalculator()
- {
- std::tm now = get_current_date();
- std::cout << "Your current year is: " << date_to_string(now) << "\n\n";
- std::cout << "What date were you born?\n";
- std::tm birthday = get_date();
- std::cout << "The date you were born is: " << date_to_string(birthday) << '\n';
- auto diff = now - birthday;
- birthday.tm_year = now.tm_year + 1;
- auto bdiff = birthday - now;
- std::cout << "You are " <<
- (diff.year != 0 ? std::to_string(diff.year) + " years, " : ""s) <<
- (diff.mon != 0 ? std::to_string(diff.mon ) + " month " : ""s) << ((diff.year || diff.mon) && diff.day ? "and " : "") <<
- (diff.day != 0 ? std::to_string(diff.day ) + " days " : ""s) << "old\n\n";
- std::cout << "There is " <<
- (bdiff.mon != 0 ? std::to_string(bdiff.mon) + " month " : ""s) << (bdiff.mon && bdiff.day ? "and " : ""s) <<
- (bdiff.day != 0 ? std::to_string(bdiff.day) + " days " : ""s) <<
- "before your next birthday where you will be " << diff.year + 1 << " years old\n";
- }
- void currentyearcalculator()
- {
- int birthyear = read<int>( "What year were you born?\n");
- int currentage = read<int>("\nWhat is your current age?\n");
- bool birthday = ask("\nHave you had your birthday this year? Y/N\n");
- int year = currentage + birthyear + (birthday ? 0 : 1);
- std::cout << "\n\nThe current year is " << year << '\n';
- }
- void birthdatecalculator()
- {
- std::tm now = get_current_date();
- int myageyear = read<int>("What is your current age in years?\n");
- int myagemonth = read<int>("\nHow many months into your age?\n");
- int myageday = read<int>("\nHow many days into your age, don't write months?\n");
- int resultday = now.tm_mday - myageday;
- int resultmonth = now.tm_mon + 1 - myagemonth;
- int resultyear = now.tm_year + 1900 - myageyear;
- if (resultday < 0) {
- resultmonth = resultmonth + 1;
- resultday = resultday + 30;
- }
- if (resultmonth < 0) {
- resultyear = resultyear + 1;
- resultmonth = resultmonth + 12;
- }
- std::cout << "This is the date you were born aprox: " << resultyear << '/' << resultmonth << '/' << resultday << '\n';
- }
- }
- void menue()
- {
- int menu = read<int>("1 for agecalculator. \n2 for current year calculator. \n3 for birthdat calculator.\nEnter another number to exit.\n\nEnter your choice here: ");
- if (menu == 1)
- date::agecalculator();
- if (menu == 2)
- date::currentyearcalculator();
- if (menu == 3)
- date::birthdatecalculator();
- }
- int main()
- {
- menue();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement