All pastes #2083348 Raw Edit

Mine

public text v1 · immutable
#2083348 ·published 2011-09-27 21:54 UTC
rendered paste body
/*********************************************************************/
/* 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();
	}

}