MATLAB: Timezone to UTC: How to add duration vector to datetime vector

datedatenumdatetimedurationtimetimezonetzoffsetutc

I want to use the new tzoffset (r2014b+) to make a function to change a datenum time vector to UTC timezone but I've encountered a strange behavior while doing operations on a datetime vector. I would like to know if I'm missing something here.
time=['2015/03/08 00:00';'2015/03/08 01:00';'2015/03/08 03:00';'2015/03/08 04:00'];
Time=datenum(time,'yyyy/mm/dd HH:MM')
date=datetime(Time,'ConvertFrom','datenum','Timezone','America/Montreal')
[UTC_Offset,dst]=tzoffset(date)
Date=date-UTC_Offset
Should give
08-Mar-2015 05:00:00
08-Mar-2015 06:00:00
08-Mar-2015 07:00:00
08-Mar-2015 08:00:00
But there's 1 extra hour being added before the daylight saving time change.
08-Mar-2015 06:00:00
08-Mar-2015 07:00:00
08-Mar-2015 07:00:00
08-Mar-2015 08:00:00
The same behavior is present when doing:
date(1)+duration(5,0,0)
So I believe something is up with the datetime vector. Does anybody else get this or I just did something wrong?

Best Answer

Frank, what's up is Daylight Saving Time, which occurred on March 8th this year. I'm guessing you knew that, but got mixed up in the time arithmetic. Here's what's going on. You have this:
>> time = ['2015/03/08 00:00';'2015/03/08 01:00';'2015/03/08 03:00';'2015/03/08 04:00'];
>> Time = datenum(time,'yyyy/mm/dd HH:MM')
Time =
736031
736031.041666667
736031.125
736031.166666667
datenums don't know anything about time zones or DST. Those times mean whatever you want them to mean. Since you then do this ...
>> date = datetime(Time,'ConvertFrom','datenum','Timezone','America/Montreal')
date =
08-Mar-2015 00:00:00
08-Mar-2015 01:00:00
08-Mar-2015 03:00:00
08-Mar-2015 04:00:00
... I assume you mean that those datenums are to be interpreted as times in the America/Montreal time zone. But what you've left out is this:
>> date.Format = [date.Format ' z']
date =
08-Mar-2015 00:00:00 UTC-5
08-Mar-2015 01:00:00 UTC-5
08-Mar-2015 03:00:00 UTC-4
08-Mar-2015 04:00:00 UTC-4
The second and third times are only an hour apart. Then this ...
>> [UTC_Offset,dst] = tzoffset(date);
>> Date = date - UTC_Offset
Date =
08-Mar-2015 06:00:00 UTC-4
08-Mar-2015 07:00:00 UTC-4
08-Mar-2015 07:00:00 UTC-4
08-Mar-2015 08:00:00 UTC-4
... adds 5 hours to the first and second times, but adds only 4 hours to the third and fourth times. But you're doing the addition in the America/Montreal time zone. Adding 5 hours to the first two puts them after the DST shift @2am, which makes them look like you added 6 hours. In other words, your array is not UTC, it's shifted America/Montreal. The easiest thing to do to get UTC times is this:
>> date.TimeZone = 'UTC'
date =
08-Mar-2015 05:00:00 UTC
08-Mar-2015 06:00:00 UTC
08-Mar-2015 07:00:00 UTC
08-Mar-2015 08:00:00 UTC
Hope this helps.