How to turn a column of seconds into the datetime-type?

86 views (last 30 days)
I have a table that looks like this:
TIME_s SD1_SPEED_MEASURED_1_rpm SD2_SPEED_MEASURED_1_rpm SD3_SPEED_MEASURED_1_rpm SD4_SPEED_MEASURED_1_rpm SD1_MOTOR_SPEED_rpm SD2_MOTOR_SPEED_rpm SD3_MOTOR_SPEED_rpm SD4_MOTOR_SPEED_rpm SD1_MOTOR_TORQUE_pct SD2_MOTOR_TORQUE_pct SD3_MOTOR_TORQUE_pct SD4_MOTOR_TORQUE_pct SD1_TORQUE_REF_B_pct SD2_TORQUE_REF_B_pct SD3_TORQUE_REF_B_pct SD4_TORQUE_REF_B_pct
______ ________________________ ________________________ ________________________ ________________________ ___________________ ___________________ ___________________ ___________________ ____________________ ____________________ ____________________ ____________________ ____________________ ____________________ ____________________ ____________________
242.2 -66.174 -69.167 -77.607 -74.388 -66.369 -69.19 -77.367 -73.986 -2.6341 -0.046144 0.34017 -0.7492 -1.97 -2.3501 -2.3501 -2.3501
242.18 -66.174 -69.167 -77.607 -74.388 -66.369 -69.19 -77.367 -73.986 -2.6341 -0.046144 0.34017 -0.7492 -1.97 -2.3501 -2.3501 -2.3501
242.16 -68.547 -72.838 -79.49 -77.035 -68.078 -72.151 -78.954 -75.901 -2.8352 -0.24927 -1.2125 -4.7041 -1.97 -1.97 -2.3501 -2.3501
242.14 -68.547 -72.838 -79.49 -77.035 -68.078 -72.151 -78.954 -75.901 -2.8352 -0.24927 -1.2125 -4.7041 -1.97 -1.97 -2.3501 -2.3501
242.12 -71.372 -75.556 -80.754 -79.204 -70.49 -74.884 -80.715 -78.217 -3.1016 -3.7407 -1.6364 -2.9571 -1.97 -1.97 -1.97 -1.97
...
0 0 0 0 0 0 0 0
Where the leftmost column records the time that has passed since the beginning of the recording in seconds. In a separate variable, I have stored the starting time of the recording in the datetime-type. In this example, the time is this:
zinterval =
datetime
18-Feb-2018 15:11:11
Now, is there any way to turn the value 0 in the column of seconds into the starting time, and then have all the following seconds be times in the datetime-type following the starting time?

Accepted Answer

Stephen23
Stephen23 on 2 Jul 2019
Edited: Stephen23 on 2 Jul 2019
The simple MATLAB solution using datetime and duration classes (no outdated datevec):
T.TIME_S = zinterval + seconds(T.TIME_s)
Note that using the variable name "TIME_s" is then a bit misleading (better would be "TIME" or something similar) and I would recommend avoiding overwriting your raw data. Here is a full working example:
>> T = array2table([242.2;242.18;242.16;242.14;242.12;0],'VariableNames',{'TIME_s'})
T =
TIME_s
______
242.2
242.18
242.16
242.14
242.12
0
>> zinterval = datetime('18-Feb-2018 15:11:11')
zinterval =
18-Feb-2018 15:11:11
>> T.TIME = zinterval + seconds(T.TIME_s)
T =
TIME_s TIME
______ ____________________
242.2 18-Feb-2018 15:15:13
242.18 18-Feb-2018 15:15:13
242.16 18-Feb-2018 15:15:13
242.14 18-Feb-2018 15:15:13
242.12 18-Feb-2018 15:15:13
0 18-Feb-2018 15:11:11
  4 Comments
Heidi Mäkitalo
Heidi Mäkitalo on 4 Jul 2019
Oh haha yes that's exactly it, now it works! If using datevec really does affect the precision of the data, I suppose I should do it this way instead.
Stephen23
Stephen23 on 4 Jul 2019
Edited: Stephen23 on 4 Jul 2019
"If using datevec really does affect the precision of the data, I suppose I should do it this way instead."
According to the datetime documentation: "datetime values have flexible display formats up to nanosecond precision", which you would definitely lose when converting to datenum or datevec and back again. Even if you do not need that much precision, a good rule of thumb is to only perform data-type conversions when required... and in this case, the conversion is not required!

Sign in to comment.

More Answers (3)

Rik
Rik on 2 Jul 2019
Edited: Rik on 2 Jul 2019
The rowfun function should be usefull here. You can convert seconds to datetime with t = datetime(Y,M,D,H,MI,S) (set the rest of the inputs to 0).
Edit:
This shows how little I work with the table format. I massively over-complicated it when trying to flesh out my answer:
clc
tab=table([250 200 150 100]',[-66 -55 -44 -33]','VariableNames',{'TIME_s','SD1_SPEED_MEASURED_1_rpm'});
zinterval = datetime(2018,02,18,15,11,11);
FieldName='TIME_s';
pos=find(ismember(tab.Properties.VariableNames,{FieldName}));
tab.(FieldName)=rowfun(@(t) add_my_date(t,zinterval),tab,...
'InputVariables',FieldName,'OutputFormat','uniform');
disp(tab)
function t=add_my_date(t,t0)
t=datenum(0,0,0,0,0,t);
t0=datenum(t0);
t=datetime(t+t0,'ConvertFrom','datenum');
end

Alex Mcaulley
Alex Mcaulley on 2 Jul 2019
Edited: Alex Mcaulley on 2 Jul 2019
Being T your table:
[Y,M,D,H,MN,S] = datevec(zinterval);
T.TIME_S = datetime(Y,M,D,H,MN,S + T.TIME_S);
  3 Comments
Stephen23
Stephen23 on 2 Jul 2019
Edited: Stephen23 on 2 Jul 2019
Note that multiple data-type conversions are not required (with accompanying loss of precision and meta-data from the datetime object).
Multiple intermediate variables are also not required.
It is not required to use outdated datevec with datetime/duration data.
See the other answers for simpler solutions without loss of precision.
EDIT: according to the MATLAB documentation, both seconds and datetime were introduced in R2014b.
Alex Mcaulley
Alex Mcaulley on 2 Jul 2019
Edited: Alex Mcaulley on 3 Jul 2019
Thanks Stephen for the comment. I am not very familiar with datetime data and I don't have seconds function in my Matlab release ;)
EDIT: Yes, I posted it without those functions (R2012b)

Sign in to comment.


Steven Lord
Steven Lord on 2 Jul 2019
There's no need to split the current date and time into parts to solve this. Let's make a reference datetime.
N = datetime('now')
Here's a vector of random seconds data.
TIME_s = cumsum([0; 10*rand(9, 1)])
Combine them. The call to seconds is necessary. If you add a datetime and a raw number, MATLAB treats the raw number as a number of days. If you'd wanted to add multiples of a different time unit (like minutes) see the "Create Date and Time Arrays" section on this documentation page.
timeFromReference = N + seconds(TIME_s)
Let's display the result with three fractional seconds in the Format so you can see the change more clearly.
timeFromReference.Format = 'dd-MMM-uuuu HH:mm:ss.SSS'
You can perform these operations on a "free" datetime array and/or array of seconds, or you can perform these same operations on arrays stored in a table array.

Products


Release

R2012b

Community Treasure Hunt

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

Start Hunting!