Middle& Middle::add_year(int n) { if(n == 0) return *this; int sign = -1; if( n > 0) { sign = 1; } if(isLeapYear()) { if(std::abs(n) > 3 && isLeapYear(year() + 4*sign)) { _numeric += (365*4 + 1 )*sign; n -= sign * 4; return add_year(n); }else if((sign > 0 && (month() < 3 && !(month() == 2 && day() == 29 ))) || (sign < 0 && (month() > 2 || (month() == 2 && day() == 29 )))) { _numeric += 366 * sign; n -= sign; return add_year(n); } } else if(isLeapYear(year() + sign) && ((( month() > 2 || (month() == 2 && day() == 29 ))&& sign > 0) || (sign < 0 && (month() < 3 && !(month() == 2 && day() == 29 ))))) { _numeric += 366 * sign; n -= sign; return add_year(n); } _numeric += 365 * sign; n -= sign; return add_year(n); }
/* * add @n months to date */ Date& Date::add_month(int n) { if (n) { int mm; int yy; yy = n / 12; mm = m + n % 12; // left n add m great than 12 if (mm > 12) { yy++; mm -= 12; } // month first m = Month(mm); if (d > month_days(m, y)) d = month_days(m, y); add_year(yy); cache->valid = false; } return *this; }
lab2::Gregorian::Gregorian(int y, int m, int d) { unsigned const yc = y; unsigned const mc = m; unsigned const dc = d; if((y == 0 && m <= 2) || y < 0 || y > 3000 || m > 12 || m < 1 || d < 1 || (int)days_in_month(mc, yc) < d || (d == 29 && m == 2 && is_leap_year(y) == 0)) { throw std::invalid_argument("Not a valid date"); } ejd = fjd; while(y >= 400) { y -= 400; ejd += 97 * 366 + 303 * 365; } while(y >= 100) { y -= 100; ejd += 24 * 366 + 76 * 365; } while(y >= 4) { y -= 4; ejd += 366 + 3 * 365; } while(y >= 1) { y --; ejd += 365; } while(m > 1) { ejd += month_lengths[m-2]; m--; } //Correct off-by-a-little problems. add_year(yc-year()); add_month(mc-month()); ejd+=(dc-day()); }
TEST(question1_test6, years_test) { actual_date.year=2012; actual_date.month=12; actual_date.day=31; add_year(actual_date); //add year expected_date.year=2013; expected_date.month=12; expected_date.day=31; CHECK_DATES(expected_date,actual_date); }
void Date::add_month(int n) { int yearShift = (int) floor( (double) (((int) _month) + n -1)/ ((int) month_this_year())); //if(n < 0){yearShift--;} add_year(yearShift); _month = ((12+(((int)_month-1+ n ) % 12)) % 12) +1; //Updating year according to removed/added number of month if(_day>days_this_month()){ _day = days_this_month(); } }
void Date:: add_day(int n) { // once every 4 years we have a leap year (366 days), vs the normal 365 days. const int leap_cycle = 365*4+1; // If a user gives us a large number (multiple years), we can speed up the process by adding 4 years at a time. int year_incr = ( n/leap_cycle) *4; // how many ears to increment (4 years in a leap cycle n %= leap_cycle; // the remaining number is guaranteed to be less then 4 years. // add support for negative n: if (n<0) { year_incr -= 4; // subtract extra 4 years n += leap_cycle; // now n is positive. And we can use the old code. } add_year( year_incr); // add this big chunk (or zero) int cur_month_length = days_in_month(m,y); // will give the number of days in a given month if (cur_month_length - d >= n) // do we stay within a given month? { // we do stay within the current month, we just change the date d += n; return; } else { // first go to the beginning of the next month: ++m; // next month if (m==Month::jan) // check if we wrapped into a new year y++; n -= (cur_month_length - d + 1); // this is what we used up from the previous month // note that if we start on the last of the month, d = cur_month_lenght, and we are using one day when we skip 31 Jan -> 1 Feb d=1; // beginning of the month cur_month_length = days_in_month(m,y); // will give the number of days in a given month while (cur_month_length - d < n){ // we can increment the full month. 1 Jan -> 1 Feb -> 1 Mar->... n -= cur_month_length; // go to the next month: 1 Jan -> 1 Feb -> 1 Mar->... ++m; // next month if (m==Month::jan) // check if we wrapped into a new year y++; cur_month_length = days_in_month(m,y); // prepare for the next iteration } // once we are here, the remaining n should be small enough to keep us within a given month. // d =1 d+= n; } }
void Date::add_month(int n) // If you add a month to 31 Jan you will get 28 or 29 Feb (depending on the leap year) { int year = n/12; int num_month = n % 12; // this should be between 0 and 11 if (num_month<0) { // support the negative n as well. year -=1; // year was already negative num_month += 12; // and now we adjusted num_month (num_month is positive) and the old code should work } int original_day = d; // need to save it, otherwise add_year can modify for 29 Feb add_year(year); // this should add the whole number of years (or subtract). Possible side-effect - modifies 29Feb. d = original_day; // This step was only required for Feb 29. for (int i=0; i<num_month; i++) { ++m; // increment the month. if (m== Month::jan) ++y; // we wrapped into the next year. } int days_in_month = 31; // most months have 31 days switch (m) { case Month::feb: // the length of February varies days_in_month = (leapyear(y))?29:28; break; case Month::apr: case Month::jun: case Month::sep: case Month::nov: days_in_month = 30; // the rest have 30 days break; } if (days_in_month<d) d = days_in_month; // set the last of the month }