It can be done in two steps: first, we "mark down" blocks; then group them. Your dataset should be presorted bu subject and date (ascending).
data have2;
set have;
by Subject;
if Date-lag(Date)>30 then Block+1;
if FIRST.Subject then Block=1;
run;
proc sql;
create table blocks as
select Subject, Block, max(Date)-min(Date) as Duration
from have2
group by Subject, Block;
quit;