4

I need to convert a datenumber to its closest end-of-month date. I found an online link but it is very inefficient for a large matrix (at http://www.mathworks.com/matlabcentral/fileexchange/26374-round-off-dates-and-times). Does Matlab (Financial Toolbox) has an inbuilt function for this? I couldn't find it.

date_in = 734421 ;
somefunction(date_in) --> Sept 2010

Thanks!

Joe Doyle
  • 6,363
  • 3
  • 42
  • 45
Maddy
  • 2,520
  • 14
  • 44
  • 64
  • 2
    What do you mean closest end of month? 734421 is 10 Oct 2010, and you want that to be Sept 2010? So would 28 Sept 2010 be Oct 2010? – abcd Jul 20 '11 at 19:31
  • Yes Yoda. Imagine that you have financial data available and you have to use the nearest end-of-month exchange rates. Thanks! – Maddy Jul 20 '11 at 19:37
  • ??? Why is end of September 2010 not closer to 28 Sep 2010 than Oct 2010??? – Jonas Heidelberg Jul 21 '11 at 18:18
  • ... I think I might get it now: can "end" can also mean "before beginning" in your case? If you have a day in September, you want the closest month (either before or after) which is NOT September itself? – Jonas Heidelberg Jul 21 '11 at 18:19
  • @Jonas Heidelberg: That's how I interpreted it based on the comments above: closest preceding or following month. Seems a little odd, but it sounds like what the OP wants. – gnovice Jul 21 '11 at 18:25
  • 1
    @gnovice I'm wondering whether one should change the title / text of the question. To me "end-of-month" is really misleading for what is actually being asked here... – Jonas Heidelberg Jul 21 '11 at 18:34

2 Answers2

6

Basically, it sounds like you are asking for whether a given date is closer to the preceding or following month. You can greatly simplify the logic involved if you use the functions EOMDAY to find the date for the end of the month and ADDTODATE to shift the current month up or down by one. Here's an example function that takes a date number as input:

function closestString = closest_month(dateNumber)

  dateVector = datevec(dateNumber);
  daysInMonth = eomday(dateVector(1),dateVector(2));
  if dateVector(3) > daysInMonth/2
    dateNumber = addtodate(dateNumber,1,'month');
  else
    dateNumber = addtodate(dateNumber,-1,'month');
  end
  closestString = datestr(dateNumber,'mmm yyyy');

end
gnovice
  • 125,304
  • 15
  • 256
  • 359
1

I had some errors in my previous version. Here's the logic incorporated into a function. It also checks for the month and updates accordingly.

function out = roundMonth(dateNumber)
    dateVector = datevec(dateNumber);
    day = dateVector(3);
    month = dateVector(2);
    year = dateVector(1);

    month = month + sign(day - 15 + double(~(month-2)))...
        + double(~(day-15 + double(~(month-2))));

    dateVector(1) = year + double((month-12)==1) - double((1-month)==1);
    dateVector(2) = mod(month,12) + 12*double(~mod(month,12));

    out = datestr(dateVector,'mmm yyyy');

EXAMPLES:

1.

roundMonth(datenum('10-Oct-2010'))

ans =

Sep 2010

2.

roundMonth(datenum('20-Oct-2010'))

ans =

Nov 2010

3.

roundMonth(datenum('20-Dec-2010'))

ans =

Jan 2011

4.

roundMonth(datenum('10-Jan-2010'))

ans =

Dec 2009
abcd
  • 41,765
  • 7
  • 81
  • 98
  • In addition, you want to be careful about edge cases like common/leap years with 28/29 days in February, so its not always comparing against 15... It is never easy dealing with dates! – Amro Jul 20 '11 at 20:03
  • @Amro: Agreed, dates are always messy. For February you just replace 15 by 14, and 28/29 is the same as 30/31. One has to settle for either 15 or 16 (or 14/15 in Feb) as midpoint, and the choice is arbitrary. I've updated to account for February and the change in year (prev Dec or next Jan). – abcd Jul 20 '11 at 20:32
  • Also - this only deals with a single date. It can't handle an array of dates. – Marc Jul 21 '11 at 13:02
  • @Marc: `datestr` does not handle vectors well. However, that part can be easily addressed by writing your own conversion function. Alternately, you can use `arrayfun` to operate on an array. – abcd Jul 21 '11 at 13:38
  • ... your `~(month-2)` stuff is to deal with the special case February, right? – Jonas Heidelberg Jul 21 '11 at 18:24
  • @Jonas: That's right. If it's February, subtract by 14 instead of 15. – abcd Jul 21 '11 at 18:25