Utilizo para eso dos funciones:
1) Una adaptación de la antigua Nanforum (da problemas en Febrero)
2) Una función propia que intenta solucionar el tema de Febrero.
Te icluyo las dos para que la adaptes a tus necesidades:
/
* File......: MADD.PRG
* Author....: Jo W. French dba Practical Computing
* Nanforum Toolkit
* Añade meses a una fecha
* dFecha la fecha inicial
* nMeses numero de meses
/
FUNCTION ADI_MES( dFecha, nMeses )
LOCAL nAdjDay, dTemp, i
// si dFecha no es tipo fecha
IF(VALTYPE(dFecha) != 'D', dFecha := DATE(), )
// si nMeses no es tipo numérico
IF(VALTYPE(nMeses) != 'N', nMeses := 0, )
nAdjDay := DAY( dFecha ) - 1 // dia del mes menos uno
dTemp := dFecha - nAdjDay // primero de mes
/ Work with 1st of months./
FOR i := 1 TO ABS(nMeses)
dTemp += IF( nMeses > 0, 31, -1 )
dTemp += 1 - DAY( dTemp )
NEXT
dTemp := MIN( (dTemp + nAdjday), (dTemp += 31 - DAY( dTemp + 31 )))
RETURN dTemp
//////////////////////////////////////////////////
/// M.Valdenebro 2006
/// Añade meses a una fecha
/// lSuma suma / .f. resta el mes
/////////////////////////////////////////////////
FUNCTION ADI_CSB ( dFecha, nMeses, nFinMes, nFinFeb, lSuma )
LOCAL nAdjDay, dTemp, i
DEFAULT lSuma := .t.
// si dFecha no es tipo fecha
IF(VALTYPE(dFecha) != 'D', dFecha := DATE(), )
// si nMeses no es tipo numérico
IF(VALTYPE(nFinMes) != 'N', nFinMes := 0, )
nAdjDay := DAY( dFecha ) - 1 // numero de dias menos UNO
dTemp := dFecha - nAdjDay // primero de mes
FOR i := 1 TO ABS(nMeses)
IF lSuma
dTemp += 31 // se va a una fecha del mes siguiente
dTemp += 1 - DAY( dTemp )
ELSE
dTemp -= 31 // se va a una fecha del mes siguiente
dTemp -= 1 - DAY( dTemp )
ENDI
NEXT
dTemp := MIN( (dTemp + nAdjday), (dTemp += 31 - DAY( dTemp + 31 )))
IF MONTH ( dFecha ) = 2 // si es febrero
IF DAY ( dFecha ) > 27 // si el dia es superior al dia 27
IF MONTH (dTemp) = 2 // si el nuevo mes es febrero
dTemp := EOM( dTemp)
ELSE // si el nuevo mes no es febrero
IF nFinFeb = 0 // Si era dia 31 en un mes 31
dTemp := EOM( dTemp)
ELSE
dTemp := EOM( dTemp) - nFinFeb
ENDI
ENDI
ENDI
ELSE
// meses de 31 dias
IF MONTH (dFecha) = 3 .or. MONTH (dFecha) = 5 .or. ;
MONTH (dFecha) = 7 .or. MONTH (dFecha) = 8 .or. ;
MONTH (dFecha) = 10 .or. MONTH (dFecha) = 12
IF DAY ( dFecha ) = 31
dTemp := EOM( dTemp)
ENDI
// meses de 30 dias
ELSEIF MONTH ( dFecha ) <> 1 // no es Enero
IF DAY ( dFecha ) = 30
IF nFinMes = 0 // Si era dia 31 en un mes 31
dTemp := EOM( dTemp)
ENDI
ENDI
ENDI
ENDI
RETURN dTemp