Date manipulation programm and it's shared library "date-manip.h" and
"libdate-manip.so". Build it as I discussed in earlier posts.
Here is program for Date manipulation in C++. You may build its shared library, as I discused in some previous blogs. Add header and attach shared library and use it's functionalities.
Here SDate is a public structure, so can be accessed to get individual elements as dd(day), MM(month) and yy(year). In string format it is complete string of date as "12/04/2034". Which is used here in all places, needed date as string in complete form and SDate to get its elements in different integer variables.
Here you need "validator shared library" and I posted already this library code.
file :- date-manip.h
--------------------
#ifndef DATE-MANIP_H_INCLUDED
#define DATE-MANIP_H_INCLUDED
#include <validator/validator.h>
#include <string>
class CDateManip
{
public:
struct SDate
{
int yy, MM, dd;
};
CDateManip();
virtual ~CDateManip();
CDateManip(const CDateManip& other);
CDateManip& operator=(const CDateManip& other);
bool splitDate(std::string strDate, SDate *dt);
void formDate(SDate dte, std::string *strDate);
bool isLeapYear(int yy);
bool isValidDate(std::string strDate);
bool julian(SDate dt, int *j);
void reverseJulian(int j,int year, SDate *dt);
bool addDays(std::string strDate, int days, std::string *strNewDate);
bool addMonths(std::string strDate, int imonths, std::string *newDate);
bool addYear(std::string strDate, int iyear, std::string *strNewDate);
int compareDate(std::string strFirstDate, std::string strSecondDate);
int diffDays(std::string strFirstDate, std::string strSecondDate);
void diffYMD(std::string strDate1, std::string strDate2, SDate *dt);
bool subDays(std::string strDate, int days, std::string *newDate);
bool subMonths(std::string strDate, int months, std::string *newDate);
bool subYears(std::string strDate, int year, std::string *newDate);
std::string weekDays(std::string strDate);
};
#endif // DATE-MANIP_H_INCLUDED
----------------------------------------------------------------------------
file :- date-manip.cpp
-----------------------------------------
#include "date-manip.h"
#include <string>
using std::string;
using std::endl;
using std::to_string;
CDateManip::CDateManip()
{
//ctor
}
CDateManip::~CDateManip()
{
//dtor
}
CDateManip::CDateManip(const CDateManip& other)
{
//copy ctor
}
CDateManip& CDateManip::operator=(const CDateManip& rhs)
{
if (this == &rhs) return *this; // handle self assignment
//assignment operator
return *this;
}
bool CDateManip::splitDate(string strDate, SDate *dt)
{
string strdd, strMM, stryy;
int diff;
bool tf;
int pos_first = strDate.find('/');
if(pos_first == string::npos)
{
return false;
}
int pos_sec = strDate.find('/', pos_first + 1);
if(pos_sec == string::npos)
{
return false;
}
diff = pos_sec - pos_first;
strdd = strDate.substr(0, pos_first);
strMM = strDate.substr(pos_first + 1, diff-1);
stryy = strDate.substr(pos_sec + 1);
tf = CValidator::intvalidator(strdd);
if(tf == false)
{
return false;
}
dt->dd = std::stoi(strdd);
tf = CValidator::intvalidator(strMM);
if(tf == false)
{
return false;
}
dt->MM = std::stoi(strMM);
tf = CValidator::intvalidator(stryy);
if(tf == false)
{
return false;
}
dt->yy = std::stoi(stryy);
}
void CDateManip::formDate(SDate dte, string *strDate)
{
if(dte.dd < 10)
{
*strDate = "0" + to_string(dte.dd);
}
else
{
*strDate = to_string(dte.dd);
}
*strDate += "/";
if(dte.MM < 10)
{
*strDate += "0" + to_string(dte.MM);
}
else
{
*strDate += to_string(dte.MM);
}
*strDate += "/";
if(dte.yy < 10)
{
*strDate += "0" + to_string(dte.yy);
}
else
{
*strDate += to_string(dte.yy);
}
}
bool CDateManip::isLeapYear(int yy)
{
if( (yy%4 == 0 && yy%100 != 0) || yy%400 == 0)
return true;
else
return false;
}
bool CDateManip::isValidDate(string strDate)
{
int dd, MM, yy;
SDate *dte = new SDate;
bool tf;
if(strDate.length() > 10)
{
return false;
}
tf = splitDate(strDate, dte);
if(tf == false)
{
return false;
}
if(dte->dd == 0 || dte->MM == 0 || dte->yy == 0) return false;
if(dte->dd < 1 || dte->dd > 31 || dte->MM < 1 || dte->MM > 12) return false;
if(dte->MM == 2)
{
if(dte->dd == 29 && (isLeapYear(dte->yy) == true )) return true;
if(dte->dd > 28) return false;
}
if(dte->MM == 4 || dte->MM == 6 || dte->MM == 9 || dte->MM == 11)
{
if(dte->dd > 30) return false;
}
delete dte;
return true;
}
bool CDateManip::julian(SDate dt, int *j)
{
if( dt.MM < 1 || dt.MM > 11)
{
return false;
}
*j = dt.dd;
switch(dt.MM - 1)
{
case 11:
*j += 30;
case 10:
*j += 31;
case 9:
*j += 30;
case 8:
*j += 31;
case 7:
*j += 31;
case 6:
*j += 30;
case 5:
*j += 31;
case 4:
*j += 30;
case 3:
*j += 31;
case 2:
*j += 28;
case 1:
*j += 31;
}
if(isLeapYear(dt.yy))
{
*j += 1;
}
return true;
}
void CDateManip::reverseJulian(int j,int year, SDate *dt)
{
int i;
int month[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(isLeapYear(year) == true)
{
month[2] = 29;
}
for(i = 1; i <= 12; i++)
{
if(j <= month[i])
{
break;
}
j -= month[i];
}
dt->yy = year;
dt->MM = i;
dt->dd = j;
}
bool CDateManip::addDays(string strDate, int days, string *strNewDate)
{
int d1,d2, m1, m2, y1, y2;
int d, m, y;
int j1, j2, diff, yrs;
int daysofyear;
SDate *dt1 = new SDate;
SDate *dt2 = new SDate;
bool tf = splitDate(strDate, dt1);
if(tf == false)
{
return false;
}
julian(*dt1, &j1);
if(isLeapYear(dt1->yy) == true)
{
diff = 366 - j1;
}
else
{
diff = 365 - j1;
}
if(days <= diff)
{
j2 = j1 + days;
dt2->yy = dt1->yy;
}
else
{
days -= diff;
dt2->yy = dt1->yy + 1;
if(isLeapYear(dt2->yy) == true)
{
daysofyear = 366;
}
else
{
daysofyear = 365;
}
while(days >= daysofyear)
{
if(isLeapYear(dt2->yy ) == true)
{
days -= 366;
}
else
{
days -= 365;
}
dt2->yy++;
daysofyear = isLeapYear(dt2->yy)?366:365;
}
j2 = days;
}
reverseJulian(j2, dt2->yy, dt2);
formDate(*dt2, strNewDate);
delete dt1, dt2;
return true;
}
bool CDateManip::addMonths(string strDate, int imonths, string *newDate)
{
SDate dt;
int quot, rem;
bool tf = splitDate(strDate, &dt);
if(tf == false)
{
return false;
}
quot = imonths / 12;
rem = imonths % 12;
dt.yy += quot;
dt.MM += rem;
if(dt.MM > 12)
{
dt.MM -= 12;
dt.yy += 1;
}
if(dt.MM == 2 && dt.dd == 29)
{
if(dt.MM == 2 && dt.dd == 29)
{
if(isLeapYear(dt.yy) == true)
{
dt.dd = 29;
}
else
{
dt.dd = 28;
}
}
}
if((dt.MM == 4 || dt.MM == 6 || dt.MM == 9 || dt.MM == 11) && dt.dd == 31)
{
dt.dd = 30;
}
formDate(dt, newDate);
return true;
}
bool CDateManip::addYear(string strDate, int iyear, string *strNewDate)
{
SDate *dte = new SDate;
bool tf = splitDate(strDate, dte);
if(tf == false)
{
return false;
}
dte->yy += iyear;
if(dte->dd == 29 && dte->MM == 2 && isLeapYear(dte->yy))
{
dte->dd = 28;
}
formDate(*dte, strNewDate);
return true;
}
int CDateManip::compareDate(string strFirstDate, string strSecondDate)
{
SDate *dt1 = new SDate;
SDate *dt2 = new SDate;
splitDate(strFirstDate, dt1);
splitDate(strSecondDate, dt2);
if(dt1->yy < dt2->yy)
return 1;
if(dt1->yy > dt2->yy)
return -1;
if(dt1->MM < dt2->MM)
return 1;
if(dt1->MM > dt2->MM)
return -1;
if(dt1->dd < dt2->dd)
return 1;
if(dt1->dd > dt2->dd)
return -1;
return 0;
}
int CDateManip::diffDays(string strFirstDate, string strSecondDate)
{
SDate dt1, dt2;
int j1, j2, days, d = 0, i;
splitDate(strFirstDate, &dt1);
splitDate(strSecondDate, &dt2);
julian(dt1, &j1);
julian(dt2, &j2);
if(dt1.yy == dt2.yy)
{
return (j2 - j1);
}
for(i = dt1.yy + 1; i <= dt2.yy-1; i++)
{
if(isLeapYear(i) == true)
{
d += 366;
}
else
{
d += 365;
}
}
if(isLeapYear(dt1.yy ) == true)
{
days = 366 - j1 + d + j2;
}
else
{
days = 365 - j1 + d + j2;
}
return days;
}
void CDateManip::diffYMD(string strDate1, string strDate2, SDate *dt)
{
SDate dt1, dt2;
splitDate(strDate1, &dt1);
splitDate(strDate2, &dt2);
if(dt2.dd < dt1.yy)
{
if(dt2.MM == 3)
{
if(isLeapYear(dt2.yy) == true)
{
dt2.dd += 29;
}
else
{
dt2.dd += 28;
}
}
else if(dt2.MM == 5 || dt2.MM == 7 || dt2.MM == 10 || dt2.MM == 12)
{
dt2.dd += 30;
}
else
{
dt2.dd += 31;
}
dt2.MM -= 1;
}
if(dt2.MM < dt1.MM)
{
dt2.yy -= 1;
dt2.MM += 12;
}
dt->yy = dt2.yy - dt1.yy;
dt->MM = dt2.MM - dt1.MM;
dt->dd = dt2.dd - dt1.dd;
}
bool CDateManip::subDays(string strDate, int days, string *newDate)
{
SDate dt1, dt2;
int j1, j2, temp;
bool tf;
splitDate(strDate, &dt1);
tf = julian(dt1, &j1);
if(tf == false)
{
return false;
}
if(days < j1)
{
j2 = j1 - days;
dt2.yy = dt1.yy;
}
else
{
days -= j1;
dt2.yy = dt1.yy - 1;
temp = isLeapYear(dt2.yy) ? 366 : 365;
while(days >= temp)
{
if(isLeapYear(dt2.yy) == true)
{
days -= 366;
}
else
{
days -= 365;
}
dt2.yy--;
temp = isLeapYear(dt2.yy) ? 366 : 365;
}
j2 = isLeapYear(dt2.yy) ? 366 - days : 365 - days;
}
SDate dt3;
reverseJulian(j2, dt2.yy, &dt3);
formDate(dt3, newDate);
return true;
}
bool CDateManip::subMonths(string strDate, int months, string *newDate)
{
SDate dt;
bool tf;
int j;
int quot;
int rem;
tf = julian(dt, &j);
if(tf == false)
{
return false;
}
quot = dt.yy / 12;
rem = dt.yy % 12;
dt.yy -= quot;
dt.MM -= rem;
if(dt.MM < 0)
{
dt.yy -= 1;
dt.MM += 12;
}
if(dt.MM == 2 && dt.dd >= 29)
{
if(isLeapYear(dt.yy) == true)
{
dt.dd = 29;
}
else if(isLeapYear(dt.yy) == false)
{
dt.dd = 28;
}
}
if( (dt.MM == 4 || dt.MM == 6 || dt.MM == 9 || dt.MM == 11) && dt.dd == 31)
{
dt.dd = 30;
}
formDate(dt, newDate);
return true;
}
bool CDateManip::subYears(string strDate, int year, string *newDate)
{
SDate dt;
bool tf = splitDate(strDate, &dt);
if(tf == true)
{
return false;
}
dt.yy -= year;
if(dt.dd == 29 && dt.MM == 2 && !isLeapYear(dt.yy))
{
dt.dd = 28;
}
formDate(dt, newDate);
return true;
}
string CDateManip::weekDays(string strDate)
{
SDate dt;
string weekday;
int j;
int f;
int h;
int fh;
splitDate(strDate, &dt);
bool tf = julian(dt, &j);
if(tf == false)
{
return false;
}
f = (dt.yy - 1)/4;
h = (dt.yy - 1)/100;
fh = (dt.yy - 1)/400;
int day = (dt.yy + j + f - h + fh) % 7;
switch(day)
{
case 0:
weekday = "Saturday";
break;
case 1:
weekday = "Sunday";
break;
case 2:
weekday = "Monday";
break;
case 3:
weekday = "Tuesday";
break;
case 4:
weekday = "Wednesday";
break;
case 5:
weekday = "Thursday";
break;
case 6:
weekday = "Friday";
break;
}
return weekday;
}