/*********************************************************************/
/* Member Function: add
*
* -= input =-
* - int ad - The days to add to the date
* - int am - The months to add to the date
* - int ay - The years to add to the date
*
* -= Description =-
* This function has a particular order of operations. First, it adds
* the days to the date. Then, it adds the months to the date.
* Finally, it adds the years to the date. This is not some kind of
* date concatenation; it's just Date + integer addition function.
* Negative arguments result in date subtraction, as you would expect.
*********************************************************************/
void Date::add( int ad, int am, int ay )
{
d += ad; // Add days.
// Now comes the part that adds or subtracts the overflowed days into months and stop when the month isn't full.
while(1)
{
if (d <= 0) // Change the subtracted month beforehand because we will be taking days based on the previous month, not the current one.
{
m--;
if (m < 1)
{
y--; // Subtract the overflowed months from one year.
if (y == 0)
{
y--; // Prevent year 0.
}
m += 12; // Increment the months by one year.
}
}
if (m == 4 or m == 6 or m == 9 or m == 11) // Odd months with 30 days
{
if (d > 30)
{
d -= 30;
} else if (d <= 0)
{
d += 30;
} else {
break;
}
} else if (m == 2) // Checks February
{
if (y % 4 == 0 and (y % 100 != 0 or y % 400 == 0)) // Leap years
{
if (d > 29)
{
d -= 29;
} else if (d <= 0)
{
d += 29;
} else {
break;
}
} else { // Normal years
if (d > 28)
{
d -= 28;
} else if (d <= 0)
{
d += 28;
} else {
break;
}
}
} else { // Any other months with 31 days
if (d > 31)
{
d -= 31;
} else if (d <= 0)
{
d += 31;
} else {
break;
}
}
if (ad > 0)
{
m++;
if (m > 12)
{
y++; // Add the overflowed months into one year.
if (y == 0)
{
y++; // Prevent year 0.
}
m -= 12; // Decrement the months by one year.
}
}
}
m += am; // Add months.
if (m > 0)
{
y += (m - (((m - 1) % 12) + 1)) / 12; // Add the overflowed months into years.
if (y == 0)
{
y++; // Prevent year 0.
}
m = ((m - 1) % 12) + 1; // Set the months back to a valid number, now that the years have been added.
} else {
y += ((m - (((m - 1) % 12) + 1)) / 12) - 1; // Subtract the overflowed months from years.
if (y == 0)
{
y--; // Prevent year 0.
}
m = ((m - 1) % 12) + 13; // Set the months back to a valid number, now that the years have been subtracted.
}
y += ay; // Add years.
if (y == 0)
{
if (ay > 0)
{
y++; // Prevent year 0.
} else {
y--; // Prevent year 0.
}
}
// If the result is, by some horrible perversion of technology, somehow invalid, then reset the date to the default.
if (!isvalid())
{
reset();
}
}