Created
January 6, 2024 20:15
-
-
Save ActuallyFro/65fe012e83bb0ceadd6979efc9acdd35 to your computer and use it in GitHub Desktop.
A wise man once wisecracked "Yeah... I'll do that the next time it's the Third Tuesday in the month again...". I was curious how to calculate that...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <cstdlib> | |
| #include <string> | |
| #include <iostream> | |
| enum Weekday { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; | |
| enum Month { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }; | |
| class ComboDate { | |
| public: | |
| int Day; | |
| int Month; | |
| int Year; | |
| int DayOfWeek; | |
| }; | |
| bool isLeapYear(int year) { | |
| return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); | |
| } | |
| std::string GetDateString(ComboDate givenDate){ | |
| std::string retString; | |
| if (givenDate.DayOfWeek == 0){ | |
| retString += "Sunday"; | |
| } else if (givenDate.DayOfWeek == 1){ | |
| retString += "Monday"; | |
| } else if (givenDate.DayOfWeek == 2){ | |
| retString += "Tuesday"; | |
| } else if (givenDate.DayOfWeek == 3){ | |
| retString += "Wednesday"; | |
| } else if (givenDate.DayOfWeek == 4){ | |
| retString += "Thursday"; | |
| } else if (givenDate.DayOfWeek == 5){ | |
| retString += "Friday"; | |
| } else if (givenDate.DayOfWeek == 6){ | |
| retString += "Saturday"; | |
| } | |
| retString += " "; | |
| if (givenDate.Month == 0){ | |
| retString += "January"; | |
| } else if (givenDate.Month == 1){ | |
| retString += "February"; | |
| } else if (givenDate.Month == 2){ | |
| retString += "March"; | |
| } else if (givenDate.Month == 3){ | |
| retString += "April"; | |
| } else if (givenDate.Month == 4){ | |
| retString += "May"; | |
| } else if (givenDate.Month == 5){ | |
| retString += "June"; | |
| } else if (givenDate.Month == 6){ | |
| retString += "July"; | |
| } else if (givenDate.Month == 7){ | |
| retString += "August"; | |
| } else if (givenDate.Month == 8){ | |
| retString += "September"; | |
| } else if (givenDate.Month == 9){ | |
| retString += "October"; | |
| } else if (givenDate.Month == 10){ | |
| retString += "November"; | |
| } else if (givenDate.Month == 11){ | |
| retString += "December"; | |
| } | |
| retString += " "; | |
| retString += std::to_string(givenDate.Day); | |
| retString += ", "; | |
| retString += std::to_string(givenDate.Year); | |
| return retString; | |
| } | |
| ComboDate GetNextYearOfCombosOccurrence(ComboDate startingDate, int maxYears = 1000000) { | |
| ComboDate nextWeekDayDateMonthOccurrence = startingDate; | |
| auto currentDayOfWeek = startingDate.DayOfWeek; | |
| auto currentMonth = startingDate.Month; | |
| auto currentDay = startingDate.Day; | |
| auto currentYear = startingDate.Year; | |
| do { | |
| currentDay++; | |
| currentDayOfWeek++; | |
| if (currentMonth == Jan || currentMonth == Mar || currentMonth == May || currentMonth == Jul || currentMonth == Aug || currentMonth == Oct || currentMonth == Dec) { | |
| if (currentDay > 31) { | |
| currentDay = 1; | |
| currentMonth++; | |
| } | |
| } | |
| else if (currentMonth == Apr || currentMonth == Jun || currentMonth == Sep || currentMonth == Nov) { | |
| if (currentDay > 30) { | |
| currentDay = 1; | |
| currentMonth++; | |
| } | |
| } | |
| else if (currentMonth == Feb) { | |
| if (isLeapYear(currentYear)) { | |
| if (currentDay > 29) { | |
| currentDay = 1; | |
| currentMonth++; | |
| } | |
| } else { | |
| if (currentDay > 28) { | |
| currentDay = 1; | |
| currentMonth++; | |
| } | |
| } | |
| } | |
| if (currentMonth > Dec) { | |
| currentMonth = Jan; | |
| currentYear++; | |
| } | |
| if (currentDayOfWeek > Saturday) { | |
| currentDayOfWeek = Sunday; | |
| } | |
| if (currentYear > startingDate.Year + maxYears) { | |
| return startingDate; | |
| } | |
| } while (currentDayOfWeek != startingDate.DayOfWeek || currentMonth != startingDate.Month || currentDay != startingDate.Day); | |
| // Update the next occurrence date | |
| nextWeekDayDateMonthOccurrence.Day = currentDay; | |
| nextWeekDayDateMonthOccurrence.Month = currentMonth; | |
| nextWeekDayDateMonthOccurrence.Year = currentYear; | |
| nextWeekDayDateMonthOccurrence.DayOfWeek = currentDayOfWeek; | |
| return nextWeekDayDateMonthOccurrence; | |
| } | |
| int main(){ | |
| ComboDate date; | |
| std::cout << "Enter weekday (0-6, Sunday-Saturday) [default: Thursday]: "; | |
| std::string weekdayInput; | |
| std::getline(std::cin, weekdayInput); | |
| date.DayOfWeek = (!weekdayInput.empty() ? std::stoi(weekdayInput) : Thursday); | |
| std::cout << "Enter month (0-11, January-December) [default: May]: "; | |
| std::string monthInput; | |
| std::getline(std::cin, monthInput); | |
| date.Month = (!monthInput.empty() ? std::stoi(monthInput) : May); | |
| std::cout << "Enter day of month [default: 28]: "; | |
| std::string dayInput; | |
| std::getline(std::cin, dayInput); | |
| date.Day = (!dayInput.empty() ? std::stoi(dayInput) : 28); | |
| std::cout << "Enter year [default: 2020]: "; | |
| std::string yearInput; | |
| std::getline(std::cin, yearInput); | |
| date.Year = (!yearInput.empty() ? std::stoi(yearInput) : 2020); | |
| ComboDate NextWeekDayDateMonthOccurrence; | |
| std::cout << "Starting Date: " << GetDateString(date) << std::endl; | |
| NextWeekDayDateMonthOccurrence = GetNextYearOfCombosOccurrence(date); | |
| std::cout << "Next Occurrence: " << GetDateString(NextWeekDayDateMonthOccurrence) << std::endl; | |
| return EXIT_SUCCESS; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment