Datatype duration midnight roll over
Afficher commentaires plus anciens
Hello,
I have a table with a series of categorical events and associated timestamp (duration datatype) at which these events happen as shown below. Typically the recordings are overnight. I want to take the timestamps and compute the differance in seconds between each successive timestamp;
Var1 Var2
... ...
'23:51:51.000' 'STAGE - N3'
'23:52:21.000' 'STAGE - R'
'00:04:51.000' 'STAGE - N1'
'00:10:21.000' 'STAGE - N2'
... ...
I have tried a couple of methods with etime() and between() etc. without much success. Seconds() and diff() works as shown below, however at midnight the roll over from 24:59:59 to 00:00:00 causes a large negitive roll over error (shown below). Is there a built in function that can handle this?
seconds(diff(myTable{:,1}))
...
30
-85650
330
30
...
Kind regards,
Christopher
Réponse acceptée
Plus de réponses (1)
Unfortunately, duration values are limited to one day, and reset at midnight. There does not appear to be any workaround for that.
Example —
t = datetime(2022,01,01) + minutes(0:2880).';
s = sin(2*pi*(0:numel(t)-1)/720);
figure
plot(t,s)
grid
tmin = t;
tmin.Format = 'HH:mm:ss';
dt = duration(string(tmin));
figure
plot(dt,s)
grid
I would just keep them as datetime values (or convert them to datetime values), and do any analyses using that result.
.
3 commentaires
Unfortunately, duration values are limited to one day, and reset at midnight.
I don't agree with this statement as written. You can have a duration array spanning more than 24 hours. Any of the components can be greater than the equivalent of 1 unit in the next largest component (like 61 seconds, 61 minutes, or 25 hours.)
y = duration(25, 61, 61)
More accurate IMO would be that data representing times of day as hours, minutes, and seconds, when converted to duration arrays, have that discontinuity at midnight.
If your data is "sorted ascending" (with any drop representing crossing that midnight discontinuity) you can use diff to identify where those discontinuities occur and add 24 hours until the time is really sorted ascending.
dt = datetime('today')+minutes([-5 5])
du = timeofday(dt)
difference = [0, diff(du)]
du(difference < 0) = du(difference < 0) + hours(24)
@Steven Lord — the duration arrays I’ve worked with, although spanning more than one day (as illustrated in my answer here) do not automatically respect days, so in this example, while the datetime values span two days, the duration values wrap at 24 hours.
When I converted my datetime values to duration values (using the string function), the duration function threw an error saying that it does not recognise 'dd/MM/yyyy HH:mm:ss' format that my datetime vector automatically provided, and specifically suggested using only the 'HH:mm:ss' section of the datetime array.
So, I did.
I have no idea what a workaround for that would be, other than to work only with datetime arrays with data that span multiple days, such as in situations like this.
The duration vector can include multiple days, however the identities of the days themselves are lost —
t = datetime(2022,01,01) + minutes(0:2880).';
s = sin(2*pi*(0:numel(t)-1)/720);
figure
plot(t,s)
grid
tmin = t;
tmin.Format = 'dd:HH:mm:ss';
dt = duration(string(tmin));
figure
plot(dt,s)
grid
.
SS, durations don't wrap at 24hrs, they really don't.
I mean, I know you know this, but just to make sure we're on the same page, datetimes represent points along the real-world time line, and durations represent elapsed time. Another interpretation is that durations repesent time along an "engineering time line" that is not measured with calendar units. In other words, elapsed time from some origin.
"converted my datetime values to duration values (using the string function)": I don't see the code for what I guess was your original stab at that, but if it was something like
dur = duration(string(dt))
then yes, duration will throw an error because the text that string returns is not in a format that the duration ctor understands: it will (almost certainly) have a y/m/d portion, and duration has no notion of calendars.
This
dur = duration(string(dt,'dd:HH:mm:ss'))
is sort of a clever hack around that error, but its kind of an accident: dd means "day of month" in datetime formats, and your datetimes start at 1-Jan, and so you get day numbers from 1 to whatever. dd means "elapsed days" in duration formats. That's why you see the ticks on your second plot like that, starting at 24hr.
There are two recommended ways to get durations from datetimes, depending on what you are wanting to do:
1) chop them off as times of day, i.e. all in [0,24) hrs: timeofday(dt)
dt = datetime(2022,7,22,0:8:48,0,0);
dur = timeofday(dt)
2) get them as a monotonically increasing sequence
dur = dt - dt(1)
So:
t = datetime(2022,01,01) + minutes(0:2880).';
s = sin(2*pi*(0:numel(t)-1)/720);
plot(t,s)
plot(t-t(1),s)
plot(t,s,DatetimeTickFormat='hh:mm:ss')
Catégories
En savoir plus sur Calendar dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!






