Level 4
#pragma warning(disable : 4996) //_CRT_SECURE_NO_WARNINGS
#pragma once
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <fstream>
#include "Course7Func.h";
using namespace std;
using namespace Course7Func;
namespace Course8Func
{
struct stDate
{
short Year;
short Month;
short Day;
};
//int GetDifferenceInDays(stDate Date1, stDate Date2);
short DayOfWeekOrder(short Day, short Month, short Year);
short DayOfWeekOrder(stDate Date);
string NumberToText(int Number)
{
if (Number == 0)
{
return "";
}
if (Number >= 1 && Number <= 19)
{
string arr[] = { "",
"One","Two","Three","Four","Five","Six","Seven",
"Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen",
"Fifteen","Sixteen","Seventeen","Eighteen","Nineteen" };
return arr[Number] + " ";
}
if (Number >= 20 && Number <= 99)
{
string arr[] = {"","","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety" };
return arr[Number / 10] + " " + NumberToText(Number % 10);
}
if (Number >= 100 && Number <= 199)
{
return "One Hundred " + NumberToText(Number % 100);
}
if (Number >= 200 && Number <= 999)
{
return NumberToText(Number / 100) + "Hundreds " + NumberToText(Number % 100);
}
if (Number >= 1000 && Number <= 1999)
{
return "One Thousand " + NumberToText(Number % 1000);
}
if (Number >= 2000 && Number <= 999999)
{
return NumberToText(Number / 1000) + "Thousands " + NumberToText(Number % 1000);
}
if (Number >= 1000000 && Number <= 1999999)
{
return "One Million " + NumberToText(Number % 1000000);
}
if (Number >= 2000000 && Number <= 999999999)
{
return NumberToText(Number / 1000000) + "Millions " + NumberToText(Number % 1000000);
}
if (Number >= 1000000000 && Number <= 1999999999)
{
return "One Billion " + NumberToText(Number % 1000000000);
}
else
{
return NumberToText(Number / 1000000000) + "Billions " + NumberToText(Number % 1000000000);
}
}
bool IsLeapYear(short Year)
{
// leap year if perfectly divisible by 400
if (Year % 400 == 0) {
return true;
}
// not a leap year if divisible by 100
// but not divisible by 400
else if (Year % 100 == 0) {
return false;
}
// leap year if not divisible by 100
// but divisible by 4
else if (Year % 4 == 0) {
return true;
}
// all other years are not leap years
else {
return false;
}
}
bool isLeapYear(short Year)
{
// if year is divisible by 4 AND not divisible by 100
// OR if year is divisible by 400
// then it is a leap year
return (Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0);
}
short ReadYear()
{
short Year;
cout << "\nPlease enter a year to check? ";
cin >> Year;
return Year;
}
short NumberOfDaysInAYear(short Year)
{
return isLeapYear(Year) ? 366 : 365;
}
short NumberOfHoursInAYear(short Year)
{
return NumberOfDaysInAYear(Year) * 24;
}
int NumberOfMinutesInAYear(short Year)
{
return NumberOfHoursInAYear(Year) * 60;
}
int NumberOfSecondsInAYear(short Year)
{
return NumberOfMinutesInAYear(Year) * 60;
}
short NumberOfDaysInAMonth(short Month, short Year)
{
if (Month < 1 || Month>12)
return 0;
if (Month == 2)
{
return isLeapYear(Year) ? 29 : 28;
}
short arr31Days[7] = { 1,3,5,7,8,10,12 };
for (short i = 1; i <= 7; i++)
{
if (arr31Days[i - 1] == Month)
return 31;
}
//if you reach here then its 30 days.
return 30;
}
short NumberOfDaysInAMonthOPT(short Month, short Year)
{
if (Month < 1 || Month>12)
return 0;
int NumberOfDays[12] = { 31,28,31,30,31,30,31,31,30,31,30,31};
return (Month == 2) ? (isLeapYear(Year) ? 29 : 28) : NumberOfDays[Month - 1];
}
short NumberOfHoursInAMonth(short Month, short Year)
{
return NumberOfDaysInAMonth(Month, Year) * 24;
}
int NumberOfMinutesInAMonth(short Month, short Year)
{
return NumberOfHoursInAMonth(Month, Year) * 60;
}
int NumberOfSecondsInAMonth(short Month, short Year)
{
return NumberOfMinutesInAMonth(Month, Year) * 60;
}
short ReadMonth()
{
short Month;
cout << "\nPlease enter a Month to check? ";
cin >> Month;
return Month;
}
short ReadDay()
{
short Day;
cout << "\nPlease enter a Day? ";
cin >> Day;
return Day;
}
short DayOfWeekOrder(short Day, short Month, short Year)
{
short a, y, m;
a = (14 - Month) / 12;
y = Year - a;
m = Month + (12 * a) - 2;
// Gregorian:
//0:sun, 1:Mon, 2:Tue...etc
return (Day + y + (y / 4) - (y / 100) + (y / 400) + ((31 * m) / 12)) % 7;
}
string DayShortName(short DayOfWeekOrder)
{
string arrDayNames[] = {
"Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
return arrDayNames[DayOfWeekOrder];
}
string MonthShortName(short MonthNumber)
{
string Months[12] = { "Jan", "Feb", "Mar",
"Apr", "May", "Jun",
"Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"
};
return (Months[MonthNumber - 1]);
}
void PrintMonthCalendar(short Month, short Year)
{
int NumberOfDays;
// Index of the day from 0 to 6
int current = DayOfWeekOrder(1, Month, Year);
NumberOfDays = NumberOfDaysInAMonth(Month, Year);
// Print the current month name
printf("\n _______________%s_______________\n\n", MonthShortName(Month).c_str());
// Print the columns
printf(" Sun Mon Tue Wed Thu Fri Sat\n");
// Print appropriate spaces
int i;
for (i = 0; i < current; i++)
{
printf(" ");
}
for (int j = 1; j <= NumberOfDays; j++)
{
printf("%4d", j);
if (++i == 7)
{
i = 0;
printf("\n");
}
}
printf("\n _________________________________\n");
}
void PrintYearCalendar(int Year)
{
printf("\n _________________________________\n\n");
printf(" Calendar - %d\n", Year);
printf(" _________________________________\n");
for (int i = 1; i <= 12; i++)
{
PrintMonthCalendar(i, Year);
}
return;
}
short NumberOfDaysFromTheBeginingOfTheYear(short Day, short Month, short Year)
{
short TotalDays = 0;
for (int i = 1; i <= Month - 1; i++)
{
TotalDays += NumberOfDaysInAMonth(i, Year);
}
TotalDays += Day;
return TotalDays;
}
stDate GetDateFromDayOrderInYear(short DateOrderInYear, short Year)
{
stDate Date;
short RemainingDays = DateOrderInYear;
short MonthDays = 0;
Date.Year = Year;
Date.Month = 1;
while (true)
{
MonthDays = NumberOfDaysInAMonth(Date.Month, Year);
if (RemainingDays > MonthDays)
{
RemainingDays -= MonthDays;
Date.Month++;
}
else
{
Date.Day = RemainingDays;
break;
}
}
return Date;
}
stDate DateAddDays(short Days, stDate Date)
{
short RemainingDays = Days + NumberOfDaysFromTheBeginingOfTheYear(Date.Day, Date.Month, Date.Year);
short MonthDays = 0;
Date.Month = 1;
while (true)
{
MonthDays = NumberOfDaysInAMonth(Date.Month, Date.Year);
if (RemainingDays > MonthDays)
{
RemainingDays -= MonthDays;
Date.Month++;
if (Date.Month > 12)
{
Date.Month = 1;
Date.Year++;
}
}
else
{
Date.Day = RemainingDays;
break;
}
}
return Date;
}
stDate ReadFullDate()
{
stDate Date;
Date.Day = ReadDay();
Date.Month = ReadMonth();
Date.Year = ReadYear();
return Date;
}
short ReadDaysToAdd()
{
short Days;
cout << "\nHow many days to add? ";
cin >> Days;
return Days;
}
bool IsDate1BeforeDate2(stDate Date1, stDate Date2)
{
return
(Date1.Year < Date2.Year) ? // �� ����� ����� ������� ����� ���� �� ����� ����� ������� �������
true : (
(Date1.Year == Date2.Year) ? // �� ��� ����ɿ
(Date1.Month < Date2.Month ? // �� ��� ����� ���� �� ��� �������
true : (Date1.Month == Date2.Month ? // �� ��� ����� ��� ��� ������
Date1.Day < Date2.Day : false) // �� ���� ������� ����� ���� �� ���� ������� �������
) : false);
}
bool IsDate1EqualDate2(stDate Date1, stDate Date2)
{
return (Date1.Year == Date2.Year) ? (
(Date1.Month == Date2.Month) ? (
(Date1.Day == Date2.Day) ? true : false
) : false
) : false;
}
bool IsLastDayInMonth(stDate Date)
{
return (
Date.Day == NumberOfDaysInAMonth(Date.Month, Date.Year)
);
}
bool IsLastMonthInYear(short Month)
{
return (Month == 12);
}
stDate IncreaseDateByOneDay(stDate Date)
{
if (IsLastDayInMonth(Date))
{
if (IsLastMonthInYear(Date.Month))
{
Date.Month = 1;
Date.Day = 1;
Date.Year++;
}
else
{
Date.Day = 1;
Date.Month++;
}
}
else
{
Date.Day++;
}
return Date;
}
int GetDifferenceInDays(stDate Date1, stDate Date2, bool IncludeEndDay = false)
{
int Days = 0;
while (IsDate1BeforeDate2(Date1, Date2))
{
Days++;
Date1 = IncreaseDateByOneDay(Date1);
}
return IncludeEndDay ? ++Days : Days;
}
stDate GetSystemDate()
{
stDate Date;
time_t t = time(0);
tm* now = localtime(&t);
Date.Year = now->tm_year + 1900;
Date.Month = now->tm_mon + 1;
Date.Day = now->tm_mday;
return Date;
}
void SwapDates(stDate& Date1, stDate& Date2)
{
stDate TempDate;
TempDate.Year = Date1.Year;
TempDate.Month = Date1.Month;
TempDate.Day = Date1.Day;
Date1.Year = Date2.Year;
Date1.Month = Date2.Month;
Date1.Day = Date2.Day;
Date2.Year = TempDate.Year;
Date2.Month = TempDate.Month;
Date2.Day = TempDate.Day;
}
//���� �� ������� ������ ��� �� ����� ���� �������� ������
int GetDifferenceInDaysSupport(stDate Date1, stDate Date2, bool IncludeEndDay = false)
{
int Days = 0;
short SawpFlagValue = 1;
if (!IsDate1BeforeDate2(Date1, Date2))
{
//Swap Dates
SwapDates(Date1, Date2);
SawpFlagValue = -1;
}
while (IsDate1BeforeDate2(Date1, Date2))
{
Days++;
Date1 = IncreaseDateByOneDay(Date1);
}
return IncludeEndDay ? ++Days * SawpFlagValue : Days * SawpFlagValue;
}
//p20 - 32
stDate IncreaseDateByXDays(short Days, stDate Date)
{
for (short i = 1; i <= Days; i++)
{
Date = IncreaseDateByOneDay(Date);
}
return Date;
}
stDate IncreaseDateByOneWeek(stDate Date)
{
for (int i = 1; i <= 7; i++)
{
Date = IncreaseDateByOneDay(Date);
}
return Date;
}
stDate IncreaseDateByXWeeks(short Weeks, stDate Date)
{
for (short i = 1; i <= Weeks; i++)
{
Date = IncreaseDateByOneWeek(Date);
}
return Date;
}
stDate IncreaseDateByOneMonth(stDate Date)
{
if (Date.Month == 12)
{
Date.Month = 1;
Date.Year++;
}
else
{
Date.Month++;
}
//last check day in date should not exceed max days in the current month
// example if date is 31/1/2022 increasing one month should not be 31 / 2 / 2022, it should
// be 28/2/2022
short NumberOfDaysInCurrentMonth =
NumberOfDaysInAMonth(Date.Month, Date.Year);
if (Date.Day > NumberOfDaysInCurrentMonth)
{
Date.Day = NumberOfDaysInCurrentMonth;
}
return Date;
}
stDate IncreaseDateByXMonths(short Months, stDate Date)
{
for (short i = 1; i <= Months; i++)
{
Date = IncreaseDateByOneMonth(Date);
}
return Date;
}
stDate IncreaseDateByOneYear(stDate Date)
{
Date.Year++;
return Date;
}
stDate IncreaseDateByXYears(short Years, stDate Date)
{
for (short i = 1; i <= Years; i++)
{
Date = IncreaseDateByOneYear(Date);
}
return Date;
}
stDate IncreaseDateByXYearsFaster(short Years, stDate Date)
{
Date.Year += Years;
return Date;
}
stDate IncreaseDateByOneDecade(stDate Date)
{
//Period of 10 years
Date.Year += 10;
return Date;
}
stDate IncreaseDateByXDecades(short Decade, stDate Date)
{
for (short i = 1; i <= Decade * 10; i++)
{
Date = IncreaseDateByOneYear(Date);
}
return Date;
}
stDate IncreaseDateByXDecadesFaster(short Decade, stDate Date)
{
Date.Year += Decade * 10;
return Date;
}
stDate IncreaseDateByOneCentury(stDate Date)
{
//Period of 100 years
Date.Year += 100;
return Date;
}
stDate IncreaseDateByOneMillennium(stDate Date)
{
//Period of 1000 years
Date.Year += 1000;
return Date;
}
//#33 to 46
stDate DecreaseDateByOneDay(stDate Date)
{
if (Date.Day == 1)
{
if (Date.Month == 1)
{
Date.Month = 12;
Date.Day = 31;
Date.Year--;
}
else
{
Date.Month--;
Date.Day = NumberOfDaysInAMonth(Date.Month, Date.Year);
}
}
else
{
Date.Day--;
}
return Date;
}
stDate DecreaseDateByXDays(short Days, stDate Date)
{
for (short i = 1; i <= Days; i++)
{
Date = DecreaseDateByOneDay(Date);
}
return Date;
}
stDate DecreaseDateByOneWeek(stDate Date)
{
for (int i = 1; i <= 7; i++)
{
Date = DecreaseDateByOneDay(Date);
}
return Date;
}
stDate DecreaseDateByXWeeks(short Weeks, stDate Date)
{
for (short i = 1; i <= Weeks; i++)
{
Date = DecreaseDateByOneWeek(Date);
}
return Date;
}
stDate DecreaseDateByOneMonth(stDate Date)
{
if (Date.Month == 1)
{
Date.Month = 12;
Date.Year--;
}
else
Date.Month--;
//last check day in date should not exceed max days in the current month
// example if date is 31/3/2022 decreasing one month should not be 31 / 2 / 2022, it should
// be 28/2/2022
short NumberOfDaysInCurrentMonth =
NumberOfDaysInAMonth(Date.Month, Date.Year);
if (Date.Day > NumberOfDaysInCurrentMonth)
{
Date.Day = NumberOfDaysInCurrentMonth;
}
return Date;
}
stDate DecreaseDateByXMonths(short Months, stDate Date)
{
for (short i = 1; i <= Months; i++)
{
Date = DecreaseDateByOneMonth(Date);
}
return Date;
}
stDate DecreaseDateByOneYear(stDate Date)
{
Date.Year--;
return Date;
}
stDate DecreaseDateByXYears(short Years, stDate Date)
{
for (short i = 1; i <= Years; i++)
{
Date = DecreaseDateByOneYear(Date);
}
return Date;
}
stDate DecreaseDateByXYearsFaster(short Years, stDate Date)
{
Date.Year -= Years;
return Date;
}
stDate DecreaseDateByOneDecade(stDate Date)
{
//Period of 10 years
Date.Year -= 10;
return Date;
}
stDate DecreaseDateByXDecades(short Decade, stDate Date)
{
for (short i = 1; i <= Decade * 10; i++)
{
Date = DecreaseDateByOneYear(Date);
}
return Date;
}
stDate DecreaseDateByXDecadesFaster(short Decade, stDate Date)
{
Date.Year -= Decade * 10;
return Date;
}
stDate DecreaseDateByOneCentury(stDate Date)
{
//Period of 100 years
Date.Year -= 100;
return Date;
}
stDate DecreaseDateByOneMillennium(stDate Date)
{
//Period of 1000 years
Date.Year -= 1000;
return Date;
}
//#47 to 53
short DayOfWeekOrder(stDate Date)
{
return DayOfWeekOrder(Date.Day, Date.Month, Date.Year);
}
short IsEndOfWeek(stDate Date)//����� ������� ��� ����� ����� ��� �����
{
return DayOfWeekOrder(Date) == 6;// ����� ������ ����
}
bool IsWeekEnd(stDate Date)
{
//Weekends are Fri and Sat
short DayIndex = DayOfWeekOrder(Date);
return (DayIndex == 5 || DayIndex == 6);
}
bool IsBusinessDay(stDate Date)
{
//Business days are Sun,Mon,Tue,Wed and Thur
/*
short DayIndex = DayOfWeekOrder(Date);
return (DayIndex >= 5 && DayIndex <= 4);
*/
//shorter method is to invert the IsWeekEnd: this will save updating code.
return !IsWeekEnd(Date);
}
short DaysUntilTheEndOfWeek(stDate Date)
{
return 6 - DayOfWeekOrder(Date);
}
short DaysUntilTheEndOfMonth(stDate Date1)
{
stDate EndOfMontDate;
EndOfMontDate.Day = NumberOfDaysInAMonth(Date1.Month, Date1.Year);
EndOfMontDate.Month = Date1.Month;
EndOfMontDate.Year = Date1.Year;
return GetDifferenceInDays(Date1, EndOfMontDate, true);
}
short DaysUntilTheEndOfYear(stDate Date1)
{
stDate EndOfYearDate;
EndOfYearDate.Day = 31;
EndOfYearDate.Month = 12;
EndOfYearDate.Year = Date1.Year;
return GetDifferenceInDays(Date1, EndOfYearDate, true);
}
//p54
// ������ ������ �������� ��� ������ ��� ���� �������
short CalculateVacationDays(stDate DateFrom, stDate DateTo)
{
short DaysCount = 0;
while (IsDate1BeforeDate2(DateFrom, DateTo))
{
if (IsBusinessDay(DateFrom))
DaysCount++;
DateFrom = IncreaseDateByOneDay(DateFrom);
}
return DaysCount;
}
//p55
// ����� ����� ������ ��� �������
// �� ������� ���� ����� �� ������ �� ���� �������
// ����� ���� ������� ������ ���� ���� ��� ���� ������� ������� �� ��� ���� ����� �������� ����� �������
stDate CalculateVacationReturnDate(stDate DateFrom, short VacationDays)
{
short WeekEndCounter = 0;
//in case the date is weekend keep adding one day util you reach business day
//we get rid of all weekends before the first business day
// �������
while (IsWeekEnd(DateFrom))
{
DateFrom = IncreaseDateByOneDay(DateFrom);
}
//here we increase the vacation dates to add all weekends to it.
for (short i = 1; i <= VacationDays + WeekEndCounter; i++)
{
if (IsWeekEnd(DateFrom))
WeekEndCounter++;
DateFrom = IncreaseDateByOneDay(DateFrom);
}
//in case the return date is week end keep adding one day util you reach business day
// �������
while (IsWeekEnd(DateFrom))
{
DateFrom = IncreaseDateByOneDay(DateFrom);
}
return DateFrom;
}
short ReadVacationDays()
{
short Days;
cout << "\nPlease enter vacation days? ";
cin >> Days;
return Days;
}
//p56
bool IsDate1AfterDate2(stDate Date1, stDate Date2)
{
return (
!IsDate1BeforeDate2(Date1, Date2) &&
!IsDate1EqualDate2(Date1, Date2)
);
}
//p57
enum enDateCompare { Before = -1, Equal = 0, After = 1 };
enDateCompare CompareDates(stDate Date1, stDate Date2)
{
if (IsDate1BeforeDate2(Date1, Date2))
return enDateCompare::Before;
if (IsDate1EqualDate2(Date1, Date2))
return enDateCompare::Equal;
/* if (IsDate1AfterDate2(Date1,Date2))
return enDateCompare::After;*/
//this is faster
return enDateCompare::After;
}
//p58
struct stPeriod
{
stDate StartDate;
stDate EndDate;
};
stPeriod ReadPeriod()
{
stPeriod Period;
cout << "\nEnter Start Date:\n";
Period.StartDate = ReadFullDate();
cout << "\nEnter End Date:\n";
Period.EndDate = ReadFullDate();
return Period;
}
bool IsOverlapPeriods(stPeriod Period1, stPeriod Period2)
{
if (
CompareDates(Period2.EndDate, Period1.StartDate) ==
enDateCompare::Before
||
CompareDates(Period2.StartDate, Period1.EndDate) ==
enDateCompare::After
)
return false;
else
return true;
}
//p59
int PeriodLengthInDays(stPeriod Period, bool IncludeEndDate = false)
{
return GetDifferenceInDays(Period.StartDate, Period.EndDate,
IncludeEndDate);
}
//p60
bool isDateInPeriod(stDate Date, stPeriod Period)
{
return !(
CompareDates(Date, Period.StartDate) ==
enDateCompare::Before
||
CompareDates(Date, Period.EndDate) ==
enDateCompare::After
);
}
//p61
int CountOverlapDays(stPeriod Period1, stPeriod Period2)
{
int Period1Length = PeriodLengthInDays(Period1, true);
int Period2Length = PeriodLengthInDays(Period2, true);
int OverlapDays = 0;
// ��� ����� ��������� ���� ����� �� ��� ������� ��� ��
if (!IsOverlapPeriods(Period1, Period2))
return 0;
// ���� ���� ��� ��� ����� ������ ������� ������� ������
// ���� ���� ���� �� ����� ���� ��� �� ����
if (Period1Length < Period2Length)
{
while (IsDate1BeforeDate2(Period1.StartDate,
Period1.EndDate))
{
if (isDateInPeriod(Period1.StartDate, Period2))
OverlapDays++;
Period1.StartDate =
IncreaseDateByOneDay(Period1.StartDate);
}
}
else
{
while (IsDate1BeforeDate2(Period2.StartDate,
Period2.EndDate))
{
if (isDateInPeriod(Period2.StartDate, Period1))
OverlapDays++;
Period2.StartDate =
IncreaseDateByOneDay(Period2.StartDate);
}
}
return OverlapDays;
}
//p62
bool IsValidDate(stDate Date)
{
if (Date.Day < 1 || Date.Day>31)
return false;
if (Date.Month < 1 || Date.Month>12)
return false;
if (Date.Month == 2)
{
if (isLeapYear(Date.Year))
{
if (Date.Day > 29)
return false;
}
else
{
if (Date.Day > 28)
return false;
}
}
short DaysInMonth = NumberOfDaysInAMonth(Date.Month, Date.Year);
if (Date.Day > DaysInMonth)
return false;
return true;
}
//p63 - 64
string DateToString(stDate Date)
{
return to_string(Date.Day) + "/" + to_string(Date.Month) +
"/" + to_string(Date.Year);
}
stDate StringToDate(string DateString)
{
stDate Date;
vector <string> vDate;
vDate = SplitString(DateString, "/");
Date.Day = stoi(vDate[0]);
Date.Month = stoi(vDate[1]);
Date.Year = stoi(vDate[2]);
return Date;
}
string ReadStringDate(string Message)
{
string DateString;
cout << Message;
getline(cin >> ws, DateString);
return DateString;
}
//p65
string ReplaceWordInString(string S1,
string StringToReplace, string sRepalceTo)
{
short pos = S1.find(StringToReplace);
while (pos != std::string::npos)
{
S1 = S1.replace(pos, StringToReplace.length(),
sRepalceTo);
pos = S1.find(StringToReplace);//find next
}
return S1;
}
string FormateDate(stDate Date,
string DateFormat = "dd/mm/yyyy")
{
string FormattedDateString = "";
FormattedDateString = ReplaceWordInString(
DateFormat,
"dd",
to_string(Date.Day));
FormattedDateString = ReplaceWordInString(
FormattedDateString,
"mm",
to_string(Date.Month)
);
FormattedDateString = ReplaceWordInString(
FormattedDateString,
"yyyy",
to_string(Date.Year)
);
return FormattedDateString;
}
}