manipulation of yearly, quarterly, monthly, weekly and daily dates using datenum

7 views (last 30 days)
I would like to create a function that translates some specific date formats into date numbers and a function that reverses the operation.
My inputs are, for example, as follows :
  • '2023' : yearly dates
  • '2023Q2' : for quarterly dates
  • '2023M3' : for monthly dates
  • '2023W30' : for weekly dates
  • '2023D153' : for daily dates
The ultimate goal would be to easily navigate betwen different date frequencies, change dates by adding or substracting some observations, etc.
My first intuition was to translate the inputs above as follows :
  • '2023' : datenum(2023,0,0) and increments of datenum(1,0,0)
  • '2023Q2' : datenum(2023,3*2,0) and increments of datenum(0,3,0)
  • '2023M3' : datenum(2023,3,1) and increments of datenum(0,1,0)
  • '2023W30' : datenum(2023,0,30*7) and increments of datenum(0,0,7)
  • '2023D153' : datenum(2023,0,153) and increments of datenum(0,0,1)
But I quickly realized this could go very wrong when I found out that
  • datenum(1,0,0) = 366
  • weeknum(datestr(datenum(2023,0,30*7))) = 30 but weeknum(datestr(datenum(1971,0,30*7)))=31
I am willing to use datenum or datetime, whatever works best in the background.
Thanks in advance

Answers (1)

John D'Errico
John D'Errico on 5 Feb 2023
Edited: John D'Errico on 5 Feb 2023
I don't see the problem. It mainly looks like you need to understand the concept of leap years. That would be crucially important to handle the first issue you tripped over.
Times in MATLAB are just floating point numbers.
format long g
now
ans =
738922.579695387
And if we do this:
datestr(now)
ans = '05-Feb-2023 13:54:45'
datestr(now+1)
ans = '06-Feb-2023 13:54:45'
So adding 1 to a datenum increments it by 1. The units of time are in DAYS. Add 1 to any time, and you get a new time that is exactly 1 day later. (I don't know if leap seconds are factored into those times. A little research would tell you though.)
When you did this:
datenum(1,0,0)
ans =
366
You were effectively asking for the number of days since the time
datestr(datenum(0,0,0))
ans = '00-Jan-0000'
datestr(datenum(1,0,0))
ans = '31-Dec-0000'
But year 0 was a leap year, if we use the current calendar. So there were 366 days in it. year 1 was not a leap year. So it had 365 days in it.
datenum(2,0,0)
ans =
731
datestr(datenum(2,0,0))
ans = '31-Dec-0001'
So where is there a problem? You seem to think you should increment by things like datenum(1,0,0) or datenum(0,3,0). But, as I said, that puts you into a problem with leap years, so a year with 366 days, and a month with sometimes 28 and sometimes 29 days.
Anyway, I'm sorry, but I won't do homework. Anwers is not a site where we do homework assignments. At most here, I'll push you in the correct direction. And that is to NOT assume that every year is the same, since some years are leap years. Don't assume that every month is the same length, just as you would not assume that the the first quarter in a year has necessarily the same number of days as the second or third or fourth quarter. If a quarter represents 3 months, then you need to use the lengths of the months in that quarter. You will need to learn the rules for leap years, but that is a simple one. Again, read the link I posted above.

Categories

Find more on Dates and Time in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!