SAS (Base SAS)+
*=============================================================================;
* Add an interval to a date using INTNX
*=============================================================================;
*-----------------------------------------------------------------------------;
* Create sample visit schedule data
*-----------------------------------------------------------------------------;
data visits;
input usubjid $ visit_dt :date9.;
format visit_dt date9.;
datalines;
S001 15JAN2025
S002 28FEB2025
S003 31MAR2025
S004 30APR2025
;
run;
*-----------------------------------------------------------------------------;
* Add various intervals using INTNX
*-----------------------------------------------------------------------------;
data visit_windows;
set visits;
* Add 30 days for next visit window;
next_30d = intnx('DAY', visit_dt, 30);
* Add 3 months - beginning of that month;
month3_b = intnx('MONTH', visit_dt, 3, 'B');
* Add 3 months - end of that month;
month3_e = intnx('MONTH', visit_dt, 3, 'E');
* Add 3 months - same day of month;
month3_s = intnx('MONTH', visit_dt, 3, 'S');
* Add 1 year - same day;
year1_s = intnx('YEAR', visit_dt, 1, 'S');
format next_30d month3_b month3_e month3_s year1_s date9.;
run;
proc print data=visit_windows noobs;
run;- We create four subjects with visit dates chosen to show edge cases: mid-month, end of February, end of March (31st), and end of April (30th).
intnx('DAY', visit_dt, 30)simply adds 30 calendar days β alignment does not matter for days.- The fourth argument of INTNX controls alignment within the target month: 'B' = beginning (1st), 'E' = end (last day), 'S' = same day, 'M' = middle (16th).
intnx('MONTH', visit_dt, 3, 'B')moves 3 months forward, then snaps to the 1st of that month β useful for reporting-period starts.intnx('MONTH', visit_dt, 3, 'E')snaps to the last day of the target month β useful for reporting-period ends.intnx('MONTH', visit_dt, 3, 'S')tries to keep the same day of month; if that day does not exist (e.g., 31st in a 30-day month), SAS rolls back to the last valid day.intnx('YEAR', visit_dt, 1, 'S')adds one year keeping the same day; Feb 28 in a non-leap year stays Feb 28.- We run PROC PRINT and check subject S002 (28FEB2025): adding 3 months with 'S' alignment should give 28MAY2025.