# count of months spanned

4 views (last 30 days)
Leah on 15 Aug 2013
I can't think of a way to do this without a loop. I have a bunch of start and end dates. Each row is a record and I want to be about to count how many months are in each date range. Here's some sample data startdates=[735406;735416;735404;735396;735363;735389]; enddates=[735433;735433;735433;735425;735416;735416];
So Jun 21-Jul 18 would be two months
>>countmonths =
2 1 2 2 3 2
My way is not very efficient
for i=1:length(startdates)
daterange=startdates(i):enddates(i);
dv=datevec(daterange);
countmonths(i)=size(unique(dv(:,[1 2]),'rows'),1);
end

Sven on 15 Aug 2013
Hi Leah,
I think you can do this quite nicely as follows:
startvecs = datevec(startdates);
endvecs = datevec(enddates);
diffvecs = endvecs - startvecs;
countmonths = 12*diffvecs(:,1) + diffvecs(:,2)+1
Does that work for you? I'm not quite sure what you'd want to do between, say, Jan1 and Feb1, but I think if you take a look at diffvecs you'll understand what it contains and be able to make it work for your purposes.
Leah on 19 Aug 2013
Thanks, this does work for me. Jan1 and Feb1 would still count as two months, which is correct for my purposes. Thanks!

Jan on 15 Aug 2013
Edited: Jan on 15 Aug 2013
When you convert the serial date numbers to date vectors you get e.g.:
s = [2013 06 21 12 13 14; ...
2013 06 21 1 2 3]
e = [2013 07 18 12 13 14; ...
2014 06 21 1 2 3]
Now the distance in months is:
(e(:, 1) * 12 + e(:, 2)) - (s(:, 1) * 12 + s(:, 2)) + 1
Or more compact:
(e(:, 1:2) - s(:, 1:2)) * [12; 1] + 1
Leah on 19 Aug 2013
Thanks Jan! This was really similar to the first post they both work great