Нужно. Важное замечание!
Мой вариант (с учётом поправки ДП):
Код: Выделить всё
DateAdd              PROCEDURE  (Date LOC:Date, Long LOC:ValueAdd, Byte LOC:Type)
LOC:Day              BYTE
LOC:Month            SHORT
LOC:Year             SHORT
  CODE
 if ~LOC:ValueAdd or not inrange(LOC:Type, 1, 3)
   return(LOC:Date)
 end
 case LOC:Type
   of 1                                                                                        ! День
         return (LOC:Date + LOC:ValueAdd)   
   of 2                                                                                        ! Месяц 
         LOC:Day = day(LOC:Date)
         if LOC:ValueAdd<0
           LOC:Year = year(LOC:Date) 
           LOC:Month = month(LOC:Date) + LOC:ValueAdd
           if LOC:Month<=0 
             LOC:Year -= (int(abs(LOC:Month) / 12) + 1)
             LOC:Month = 12 - abs(LOC:Month) % 12 
             if LOC:Month=0
               LOC:Month = 12
             end  
           end  
           LOC:Date = date(LOC:Month, LOC:Day, LOC:Year)
         else
           LOC:Date = date(month(LOC:Date) + LOC:ValueAdd, LOC:Day, year(LOC:Date))
         end
         if day(LOC:Date)<LOC:Day
           return date(month(LOC:Date), 1, year(LOC:Date)) - 1
         else
           return LOC:Date
         end  
   of 3                                                                                        ! Год
         if month(LOC:Date)=2
           LOC:Day = day(LOC:Date)
           LOC:Date = date(month(LOC:Date), day(LOC:Date), year(LOC:Date) + LOC:ValueAdd)
           if day(LOC:Date)<LOC:Day
             return date(month(LOC:Date), 1, year(LOC:Date)) - 1
           else
             return LOC:Date
           end  
         else
           return date(month(LOC:Date), day(LOC:Date), year(LOC:Date) + LOC:ValueAdd)
         end  
 end


