Loren on the Art of MATLAB

Turn ideas into MATLAB


Loren on the Art of MATLAB has been archived and will not be updated.

Setting a New Time Basis for Date / Time Data

I was recently working with someone who had some temporal data in various formats and was trying to merge them in a meaningful way.


Problem Setup

I made a small subset of the data and loaded it in.

load setTimeBasis
  Name           Size            Bytes  Class       Attributes

  mydatestr      1x6                12  char                  
  t              5x1               161  datetime              

First I looked at the both variables.

mydatestr =
t = 

You can see that I have a string representing a date (May 6, 2009), and then a datetime array in t. Though I saw that t was a datetime, I kept thinking of it as a duration since I didn't see a month, year, etc. And I have to confess, though I usually do check the documentation, I was really resisting it yesterday - not sure why - perhaps I was being more obstinate than usual :-) !

What Didn't Work

Next I converted the base date to datetime, and tried adding it to t.

d = datetime('090506','InputFormat','MMddyy')
     d + t
catch E
d = 
Addition is not defined between datetime arrays.

First Working Shot

Ok, so that didn't work. I finally realized that even though t was only displaying hours, minutes, and seconds, because it was a datetime array and not a duration, I had to deal with that! I also realized that I used the wrong formatting for converting the original date for mydatestr to a datetime! What was I thinking!

newdate = datetime(mydatestr,'InputFormat','yyMMdd')
newdate = 

Let's inspect the first time point now.

t1 = t(1);
[year(t1) month(t1) day(t1)]
ans =
        2016           6           7

Aha! Now I need to convert the date (not time) values in t to that in olddate! I can do this by computing the difference in dates, leading to a duration array which I can add to the base date.

olddate = datetime(year(t1),month(t1),day(t1));
datediff = newdate - olddate
newt = t + datediff
datediff = 
newt = 

Let's check out what's in newt now (I know, eye(newt)!)

newt1 = newt(1);
newt1.Format = 'yy-MM-dd hh:mm:ss'
newt1 = 
   09-05-06 12:32:28

Much Better Answer

Frankly, I got it to work but it was really ugly and somewhat contorted. Had I responsibly read the documentation before, I just might have found a better way. Instead of showing you the doc right now, I will show you another way to poke for more information. Let's find out what I can do with a datetime array.

Methods for class datetime:

between            hour               le                 reshape            
caldiff            interp1            length             second             
cat                intersect          linspace           setdiff            
cellstr            isbetween          lt                 setxor             
char               iscolumn           max                size               
colon              isdst              mean               sort               
ctranspose         isempty            median             sortrows           
datenum            isequal            min                std                
dateshift          isequaln           minus              timeofday          
datestr            isfinite           minute             transpose          
datetime           isinf              mode               tzoffset           
datevec            ismatrix           month              union              
day                ismember           ndims              unique             
diff               isnat              ne                 vertcat            
eq                 isrow              numel              week               
exceltime          isscalar           permute            year               
ge                 issorted           plot               ymd                
gt                 isvector           plus               yyyymmdd           
hms                isweekend          posixtime          
horzcat            juliandate         quarter            

Static methods:


Hmmmm! timeofday sure sounds interesting, doesn't it!?! So let's try again.

newdate = datetime(mydatestr,'InputFormat','yyMMdd')
tod = timeofday(t)
newt2 = newdate + tod
newdate = 
tod = 
newt2 = 
   06-May-2009 12:32:28
   06-May-2009 12:59:50
   06-May-2009 12:59:51
   06-May-2009 12:59:52
   06-May-2009 12:59:53
  Name           Size            Bytes  Class         Attributes

  E              1x1              3106  MException              
  ans            1x3                24  double                  
  d              1x1               121  datetime                
  datediff       1x1               128  duration                
  mydatestr      1x6                12  char                    
  newdate        1x1               121  datetime                
  newt           5x1               201  datetime                
  newt1          1x1               147  datetime                
  newt2          5x1               185  datetime                
  olddate        1x1               121  datetime                
  t              5x1               161  datetime                
  t1             1x1               129  datetime                
  tod            5x1               160  duration                

So now we have decent working code, much nicer than the first successful attempt too!


This also could have been done with a for-loop instead of working on the arrays as arrays. For a larger set of data, my colleague found that a for-loop solution (including working with the old-style datestr etc. tools) took 29.0 seconds, and the first vectorized version took 2.3 seconds. I'm guessing the second attempt is faster but didn't bother timing it.

And You?

Have you been using the new date and time features, starting with Release R2014b? What have you had success or struggled with? Let us know here.

In case it helps you, we also have a short video about datetime that you might be interested in. Happy computing!

Published with MATLAB® R2016a

  • print


To leave a comment, please click here to sign in to your MathWorks Account or create a new one.