easy way to add 1 month to a time_t in C/C++

后端 未结 4 1670
小蘑菇
小蘑菇 2021-01-13 01:51

I have some code that uses the Oracle function add_months to increment a Date by X number of months.

I now need to re-implement the same logic in a C / C++ function.

4条回答
  •  渐次进展
    2021-01-13 02:24

    Method AddMonths_OracleStyle does what you need.

    Perhaps you would want to replace IsLeapYear and GetDaysInMonth to some librarian methods.

    #include 
    #include 
    
    bool IsLeapYear(int year) 
    {
        if (year % 4 != 0) return false;
        if (year % 400 == 0) return true;
        if (year % 100 == 0) return false;
        return true;
    }
    
    int daysInMonths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    int GetDaysInMonth(int year, int month)
    {
        assert(month >= 0);
        assert(month < 12);
    
        int days = daysInMonths[month];
    
        if (month == 1 && IsLeapYear(year)) // February of a leap year
            days += 1;
    
        return days;
    }
    
    tm AddMonths_OracleStyle(const tm &d, int months)
    {
        bool isLastDayInMonth = d.tm_mday == GetDaysInMonth(d.tm_year, d.tm_mon);
    
        int year = d.tm_year + months / 12;
        int month = d.tm_mon + months % 12;
    
        if (month > 11)
        {
            year += 1;
            month -= 12;
        }
    
        int day;
    
        if (isLastDayInMonth)
            day = GetDaysInMonth(year, month); // Last day of month maps to last day of result month
        else
            day = std::min(d.tm_mday, GetDaysInMonth(year, month));
    
        tm result = tm();
    
        result.tm_year = year;
        result.tm_mon = month;
        result.tm_mday = day;
    
        result.tm_hour = d.tm_hour;
        result.tm_min = d.tm_min;
        result.tm_sec = d.tm_sec;
    
        return result;
    }
    
    time_t AddMonths_OracleStyle(const time_t &date, int months)
    {
        tm d = tm();
    
        localtime_s(&d, &date);
    
        tm result = AddMonths_OracleStyle(d, months);
    
        return mktime(&result);
    }
    

提交回复
热议问题