DATE_ADD gives strange results when using negative days or weeks.
This is because the conversion from int to udint, which interpretes the sign bit wrong.
DATE_ADD := UDINT_TO_DATE(DATE_TO_UDINT(IDATE) + INT_TO_UDINT(D + W * 7) * UDINT#86400);
Here is my proposal:
day := D + W * 7;
IF day >= 0 THEN
DATE_ADD := IDATE + INT_TO_UDINT(day) * UDINT#86400;
ELSE
DATE_ADD := IDATE - INT_TO_UDINT(ABS(day)) * UDINT#86400;
END_IF;