How to turn a column of seconds into the datetime-type?
47 ビュー (過去 30 日間)
古いコメントを表示
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?
0 件のコメント
採用された回答
Stephen23
2019 年 7 月 2 日
編集済み: Stephen23
2019 年 7 月 2 日
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 件のコメント
Stephen23
2019 年 7 月 4 日
編集済み: Stephen23
2019 年 7 月 4 日
"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!
その他の回答 (3 件)
Rik
2019 年 7 月 2 日
編集済み: Rik
2019 年 7 月 2 日
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
2019 年 7 月 2 日
編集済み: Alex Mcaulley
2019 年 7 月 2 日
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 件のコメント
Stephen23
2019 年 7 月 2 日
編集済み: Stephen23
2019 年 7 月 2 日
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.
Alex Mcaulley
2019 年 7 月 2 日
編集済み: Alex Mcaulley
2019 年 7 月 3 日
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)
Steven Lord
2019 年 7 月 2 日
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.
参考
カテゴリ
Help Center および File Exchange で Time Series Objects についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!