Skip to content

Instantly share code, notes, and snippets.

@JamesBremner
Last active November 27, 2023 18:15
Show Gist options
  • Save JamesBremner/fa383ac1e01a7d9e09e1fceccfa1b077 to your computer and use it in GitHub Desktop.
Save JamesBremner/fa383ac1e01a7d9e09e1fceccfa1b077 to your computer and use it in GitHub Desktop.
Display Calendars
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <time.h>
/// Display a base calendar
class cCalendar
{
protected:
std::time_t myTime;
int myMonthCount;
void displayDay();
void displayMonthHead(const struct tm &day);
/// @brief Display day of month
/// @param day
///
/// Overwrite in specialised calendar class with an additional character
virtual void decorateDay(const struct tm &day);
public:
/// @brief CTOR, specifying start day
/// @param year
/// @param month
/// @param day
cCalendar(
int year,
int month, // 0 - 11
int day); // 1 - 31
/// @brief Display the calendar
/// @param monthCount number of months to display
void display(int monthCount);
};
/** @brief Specialized calendar class to show 'w' on working days
There are three different shift patterns for a week: A, B, and C.
The shift pattern changes each week, starting on Monday, cycling through A,B,C and repeating
A has Fri & Sat off
B has Thus & Sun off
C has Tues & Wed off
*/
class cShiftCalendar : public cCalendar
{
public:
cShiftCalendar(
int year,
int month, // 0 - 11
int day) // 1 - 31
: cCalendar(year, month, day)
{
}
void decorateDay(const struct tm &day);
};
cCalendar::cCalendar(
int year,
int month, // 0 - 11
int day) // 1 - 31
{
struct tm tmDay = {0};
tmDay.tm_year = year - 1900;
tmDay.tm_mon = month;
tmDay.tm_mday = day;
tmDay.tm_hour = 12; // set to noon to avoid daylight saving time issues
myTime = mktime(&tmDay);
}
void cCalendar::display(int monthCount)
{
myMonthCount = monthCount + 1;
while (myMonthCount)
{
displayDay();
myTime += 24 * 60 * 60;
}
}
void cCalendar::displayDay()
{
struct tm day = *localtime(&myTime);
if (day.tm_mday == 1)
{
// first day of a new month
myMonthCount--;
if (!myMonthCount)
return;
displayMonthHead(day);
}
std::string sday = std::to_string(day.tm_mday);
if (sday.length() == 1)
std::cout << " ";
std::cout << sday;
decorateDay(day);
if (day.tm_wday == 0)
std::cout << "\n";
}
void cCalendar::displayMonthHead(const struct tm &day)
{
const std::string smonth[12]{"Jan", "Feb", "Mar"};
std::cout << "\n\n"
<< smonth[day.tm_mon] << "\n Mo Tu We Th Fr Sa Su\n";
int empty = day.tm_wday - 1;
if (empty == -1)
empty = 6;
for (int k = 0; k < 4 * empty; k++)
std::cout << " ";
}
void cCalendar::decorateDay(const struct tm &day)
{
std::cout << " ";
}
void cShiftCalendar::decorateDay(const struct tm &day)
{
static int cycle = 0;
if (day.tm_wday == 1)
{
// monday cycle change
cycle++;
if (cycle > 3)
cycle = 1;
}
bool work = true;
switch (cycle)
{
case 1:
// off fri & Sat
if (day.tm_wday == 5 ||
day.tm_wday == 6)
work = false;
break;
case 2:
// off thu & sun
if (day.tm_wday == 0 ||
day.tm_wday == 4)
work = false;
break;
case 3:
// off tues and wed
if (day.tm_wday == 2 ||
day.tm_wday == 3)
work = false;
break;
}
if (work)
std::cout << "w ";
else
std::cout << " ";
}
main()
{
cShiftCalendar calendar(2024, 0, 1);
calendar.display(3);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment