how to select an interval of certain hours each day within a larger timetable using timerange
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
Hi, I have a timetable of minute by minute data running over multiple days. I wish to identify the times outside regular business hours (9 am to 5 pm) in order to (later) process that data differently from the rest. How do I do this using the timerange function? In other words, how do I select a timerange within each day, for every day, without selecting any full days? Thanks
Accepted Answer
Star Strider
on 26 Mar 2022
The timerange function operates on timetable arrays, so to use it, the data must be in a timetable and the times must be duration arrays.
This uses table2timetable and duration array conversion —
DT = datetime('26-Mar-2022') + minutes(0:1440*2)'; % Two Days
Data = randn(numel(DT),3); % Create Other Values
T1 = [table(DT) array2table(Data)]
T1 = 2881×4 table
DT Data1 Data2 Data3
____________________ __________ ________ ________
26-Mar-2022 00:00:00 -0.6546 -0.31415 2.4173
26-Mar-2022 00:01:00 -0.20845 -0.89936 -2.3631
26-Mar-2022 00:02:00 -0.20717 0.55078 0.25069
26-Mar-2022 00:03:00 1.5701 -0.2149 -0.48116
26-Mar-2022 00:04:00 1.3051 -0.62446 0.89712
26-Mar-2022 00:05:00 -0.0059697 0.10382 0.90953
26-Mar-2022 00:06:00 -0.27235 1.0921 -0.53748
26-Mar-2022 00:07:00 1.5568 0.38122 1.2537
26-Mar-2022 00:08:00 -2.1977 1.0529 -1.6526
26-Mar-2022 00:09:00 1.9246 0.68009 -1.306
26-Mar-2022 00:10:00 -0.12461 0.48482 -1.4169
26-Mar-2022 00:11:00 -0.63642 0.081571 -0.11844
26-Mar-2022 00:12:00 0.92942 0.73651 -0.56618
26-Mar-2022 00:13:00 -0.17877 -0.33336 0.33599
26-Mar-2022 00:14:00 -0.41219 -0.85676 -0.80945
26-Mar-2022 00:15:00 0.13819 -0.17675 2.2606
TT1 = table2timetable(T1);
TT1.DT = duration(hour(TT1.DT),minute(TT1.DT),second(TT1.DT))
TT1 = 2881×3 timetable
DT Data1 Data2 Data3
________ __________ ________ ________
00:00:00 -0.6546 -0.31415 2.4173
00:01:00 -0.20845 -0.89936 -2.3631
00:02:00 -0.20717 0.55078 0.25069
00:03:00 1.5701 -0.2149 -0.48116
00:04:00 1.3051 -0.62446 0.89712
00:05:00 -0.0059697 0.10382 0.90953
00:06:00 -0.27235 1.0921 -0.53748
00:07:00 1.5568 0.38122 1.2537
00:08:00 -2.1977 1.0529 -1.6526
00:09:00 1.9246 0.68009 -1.306
00:10:00 -0.12461 0.48482 -1.4169
00:11:00 -0.63642 0.081571 -0.11844
00:12:00 0.92942 0.73651 -0.56618
00:13:00 -0.17877 -0.33336 0.33599
00:14:00 -0.41219 -0.85676 -0.80945
00:15:00 0.13819 -0.17675 2.2606
BusinessHours = timerange(hours(9), hours(17), 'closed'); % 09:00 To 17:00
TT1_BusinessHours = TT1(BusinessHours,:)
TT1_BusinessHours = 962×3 timetable
DT Data1 Data2 Data3
________ ________ _________ _________
09:00:00 -1.724 0.11354 -0.20664
09:01:00 -0.74624 -0.22058 -0.041664
09:02:00 1.2126 1.5414 1.0954
09:03:00 1.1506 0.4756 -1.3082
09:04:00 0.67332 0.95748 0.61051
09:05:00 1.5053 -0.35985 -0.13002
09:06:00 0.20755 -0.75411 -0.53651
09:07:00 -0.778 -0.96918 -0.28845
09:08:00 1.6209 -0.91014 0.40509
09:09:00 -0.59304 -0.0521 -0.59109
09:10:00 0.80869 -1.5248 -0.71053
09:11:00 0.84078 -0.055333 -0.36499
09:12:00 -0.96482 -0.62741 -0.49314
09:13:00 2.021 -0.95608 0.4493
09:14:00 0.1844 1.2234 0.14406
09:15:00 1.1104 0.38988 0.90148
OtherHours1 = timerange(hours(0),hours(9),'open'); % Midnight To 09:00
OtherHours2 = timerange(hours(17), hours(24), 'open'); % 17:00 To Midnight
TT1_OtherHours = [TT1(OtherHours1,:); TT1(OtherHours2,:)]
TT1_OtherHours = 1916×3 timetable
DT Data1 Data2 Data3
________ __________ ________ ________
00:01:00 -0.20845 -0.89936 -2.3631
00:02:00 -0.20717 0.55078 0.25069
00:03:00 1.5701 -0.2149 -0.48116
00:04:00 1.3051 -0.62446 0.89712
00:05:00 -0.0059697 0.10382 0.90953
00:06:00 -0.27235 1.0921 -0.53748
00:07:00 1.5568 0.38122 1.2537
00:08:00 -2.1977 1.0529 -1.6526
00:09:00 1.9246 0.68009 -1.306
00:10:00 -0.12461 0.48482 -1.4169
00:11:00 -0.63642 0.081571 -0.11844
00:12:00 0.92942 0.73651 -0.56618
00:13:00 -0.17877 -0.33336 0.33599
00:14:00 -0.41219 -0.85676 -0.80945
00:15:00 0.13819 -0.17675 2.2606
00:16:00 0.22279 -1.2399 -0.43212
Using timerange is not as straightforward as I thought it would be, and I had to ‘fractionate’ it to get it to work.
% figure
% plot(TT1_BusinessHours.DT, TT1_BusinessHours.Data1)
% figure
% plot(TT1_OtherHours.DT, TT1_OtherHours.Data1)
.
6 Comments
Yes,I am also surprised there is not a more straightforward method. The data is in a timetable labeled by datetime. So it looks like I will have to take each day's data out one day at a time, do the multistep process above, then put it back in a timetable with datetime row labels? Because it looks like in going from datetime to duration labels the dd-mm-yyyy info is dropped.
That‘s correct.
It might be more straightforward to use the isbetween function. It creates a logical vector, and works with both datetime and duration arrays (according to the documentation) so using the conventions in my code, the two groups would be:
BusinessHours = isbetween(TT1,hours(9),hours(17),'open');
OtherHours = TT1(~BusinessHours,:);
DT = datetime('26-Mar-2022') + minutes(0:1440*2)'; % Two Days
Data = randn(numel(DT),3); % Create Other Values
T1 = [table(DT) array2table(Data)];
TT1 = table2timetable(T1)
TT1 = 2881×3 timetable
DT Data1 Data2 Data3
____________________ ________ _________ ________
26-Mar-2022 00:00:00 0.0089 1.0802 0.052403
26-Mar-2022 00:01:00 -0.42752 -0.032435 -2.6591
26-Mar-2022 00:02:00 -0.16621 -0.23301 0.86686
26-Mar-2022 00:03:00 -0.15177 0.26352 -0.01072
26-Mar-2022 00:04:00 0.69538 -1.2334 0.61313
26-Mar-2022 00:05:00 -0.29458 0.12531 -0.31381
26-Mar-2022 00:06:00 -0.43038 -0.97858 1.4499
26-Mar-2022 00:07:00 -1.2165 -0.013836 1.7829
26-Mar-2022 00:08:00 0.51098 0.31623 0.13328
26-Mar-2022 00:09:00 0.47328 0.80642 0.42304
26-Mar-2022 00:10:00 0.94732 0.39715 1.4349
26-Mar-2022 00:11:00 -0.17398 -1.3395 1.1198
26-Mar-2022 00:12:00 1.3644 0.11788 -0.73741
26-Mar-2022 00:13:00 0.85061 0.074006 -1.0366
26-Mar-2022 00:14:00 0.78419 -1.9073 -1.03
26-Mar-2022 00:15:00 -0.91914 -1.0953 0.038323
TT1.DT = duration(hour(TT1.DT),minute(TT1.DT),second(TT1.DT))
TT1 = 2881×3 timetable
DT Data1 Data2 Data3
________ ________ _________ ________
00:00:00 0.0089 1.0802 0.052403
00:01:00 -0.42752 -0.032435 -2.6591
00:02:00 -0.16621 -0.23301 0.86686
00:03:00 -0.15177 0.26352 -0.01072
00:04:00 0.69538 -1.2334 0.61313
00:05:00 -0.29458 0.12531 -0.31381
00:06:00 -0.43038 -0.97858 1.4499
00:07:00 -1.2165 -0.013836 1.7829
00:08:00 0.51098 0.31623 0.13328
00:09:00 0.47328 0.80642 0.42304
00:10:00 0.94732 0.39715 1.4349
00:11:00 -0.17398 -1.3395 1.1198
00:12:00 1.3644 0.11788 -0.73741
00:13:00 0.85061 0.074006 -1.0366
00:14:00 0.78419 -1.9073 -1.03
00:15:00 -0.91914 -1.0953 0.038323
BusinessHours = isbetween(TT1.DT,hours(9),hours(17),'open'); % 09:00 To 17:00
TT1_BusinessHours = TT1(BusinessHours,:)
TT1_BusinessHours = 958×3 timetable
DT Data1 Data2 Data3
________ ________ ________ ________
09:01:00 0.73257 0.27795 0.13411
09:02:00 0.61368 -2.2987 -0.11546
09:03:00 0.96921 -0.17803 -1.2016
09:04:00 1.0591 -0.25522 0.041641
09:05:00 0.86261 -0.11875 -1.1432
09:06:00 0.19201 -0.57453 -0.98597
09:07:00 0.43657 1.9273 -0.93695
09:08:00 -0.72754 0.38783 0.42892
09:09:00 -0.76209 0.032867 -0.15609
09:10:00 -0.62209 0.10424 -0.97316
09:11:00 -1.6538 1.872 2.4745
09:12:00 -1.1019 0.71403 2.0267
09:13:00 1.3847 -0.21659 0.60601
09:14:00 -1.0233 -1.3663 -0.22932
09:15:00 0.14303 -0.16536 -1.4742
09:16:00 0.015824 -0.24718 -0.46047
TT1_OtherHours = TT1(~BusinessHours,:)
TT1_OtherHours = 1923×3 timetable
DT Data1 Data2 Data3
________ ________ _________ ________
00:00:00 0.0089 1.0802 0.052403
00:01:00 -0.42752 -0.032435 -2.6591
00:02:00 -0.16621 -0.23301 0.86686
00:03:00 -0.15177 0.26352 -0.01072
00:04:00 0.69538 -1.2334 0.61313
00:05:00 -0.29458 0.12531 -0.31381
00:06:00 -0.43038 -0.97858 1.4499
00:07:00 -1.2165 -0.013836 1.7829
00:08:00 0.51098 0.31623 0.13328
00:09:00 0.47328 0.80642 0.42304
00:10:00 0.94732 0.39715 1.4349
00:11:00 -0.17398 -1.3395 1.1198
00:12:00 1.3644 0.11788 -0.73741
00:13:00 0.85061 0.074006 -1.0366
00:14:00 0.78419 -1.9073 -1.03
00:15:00 -0.91914 -1.0953 0.038323
T1_BusinessHours = T1(BusinessHours,:)
T1_BusinessHours = 958×4 table
DT Data1 Data2 Data3
____________________ ________ ________ ________
26-Mar-2022 09:01:00 0.73257 0.27795 0.13411
26-Mar-2022 09:02:00 0.61368 -2.2987 -0.11546
26-Mar-2022 09:03:00 0.96921 -0.17803 -1.2016
26-Mar-2022 09:04:00 1.0591 -0.25522 0.041641
26-Mar-2022 09:05:00 0.86261 -0.11875 -1.1432
26-Mar-2022 09:06:00 0.19201 -0.57453 -0.98597
26-Mar-2022 09:07:00 0.43657 1.9273 -0.93695
26-Mar-2022 09:08:00 -0.72754 0.38783 0.42892
26-Mar-2022 09:09:00 -0.76209 0.032867 -0.15609
26-Mar-2022 09:10:00 -0.62209 0.10424 -0.97316
26-Mar-2022 09:11:00 -1.6538 1.872 2.4745
26-Mar-2022 09:12:00 -1.1019 0.71403 2.0267
26-Mar-2022 09:13:00 1.3847 -0.21659 0.60601
26-Mar-2022 09:14:00 -1.0233 -1.3663 -0.22932
26-Mar-2022 09:15:00 0.14303 -0.16536 -1.4742
26-Mar-2022 09:16:00 0.015824 -0.24718 -0.46047
T1_OtherHours = T1(~BusinessHours,:)
T1_OtherHours = 1923×4 table
DT Data1 Data2 Data3
____________________ ________ _________ ________
26-Mar-2022 00:00:00 0.0089 1.0802 0.052403
26-Mar-2022 00:01:00 -0.42752 -0.032435 -2.6591
26-Mar-2022 00:02:00 -0.16621 -0.23301 0.86686
26-Mar-2022 00:03:00 -0.15177 0.26352 -0.01072
26-Mar-2022 00:04:00 0.69538 -1.2334 0.61313
26-Mar-2022 00:05:00 -0.29458 0.12531 -0.31381
26-Mar-2022 00:06:00 -0.43038 -0.97858 1.4499
26-Mar-2022 00:07:00 -1.2165 -0.013836 1.7829
26-Mar-2022 00:08:00 0.51098 0.31623 0.13328
26-Mar-2022 00:09:00 0.47328 0.80642 0.42304
26-Mar-2022 00:10:00 0.94732 0.39715 1.4349
26-Mar-2022 00:11:00 -0.17398 -1.3395 1.1198
26-Mar-2022 00:12:00 1.3644 0.11788 -0.73741
26-Mar-2022 00:13:00 0.85061 0.074006 -1.0366
26-Mar-2022 00:14:00 0.78419 -1.9073 -1.03
26-Mar-2022 00:15:00 -0.91914 -1.0953 0.038323
So using isbetween is likely more efficient (and much easier to code). Unfortunately, to have it work over multiple days, the time variable must be a duration. However, once it is defined, it can be used with the original table so that may be the best option. That required a bit of experimentation to fully appreciate. It would likely also work on the original timetable prior to converting the time variable to a duration array.
This may be the only way to make it work, so do the time segmentation on the duration array (that can probably be created specifically to use it with isbetween to create the logical vector), and do the rest of the calculations on the original timetable, after applying the isbetween logical vector to it.
.
You put a lot of thought into this on my behalf, and I am grateful. Something like this should work. Kevin
As always, my pleasure!
Just tried running your code as is, but get an error message:
DT = datetime('26-Mar-2022') + minutes(0:1440*2)'; % Two Days
Data = randn(numel(DT),3); % Create Other Values
T1 = [table(DT) array2table(Data)];
TT1 = table2timetable(T1)
TT1.DT = duration(hour(TT1.DT),minute(TT1.DT),second(TT1.DT))
BusinessHours = isbetween(TT1.DT,hours(9),hours(17),'open'); % 09:00 To 17:00
TT1_BusinessHours = TT1(BusinessHours,:)
TT1_OtherHours = TT1(~BusinessHours,:)
"Unable to use a value of type 'datetime' as an index.
Error in untitled9 (line 23)
TT1.DT = duration(hour(TT1.DT),minute(TT1.DT),second(TT1.DT))"
Star Strider
on 26 Mar 2022
Edited: Star Strider
on 26 Mar 2022
In MATLAB, indices must be integers greater than 0 or logical values.
I note that you are using R2019a and I (and the online Run feature here) are using R2022a. There very well could be version differences, however that line:
TT1.DT = duration(hour(TT1.DT),minute(TT1.DT),second(TT1.DT))
simply converts ‘TT1.DT’ into a duration array by extracting the hour, minute, and second from the datetime array to create it. Looking at the R2019a documentation, the duration and hour (and I assume the others) do not appear to have changed. I am at a loss to explain the inconsistency, or the error.
It runs correctly in my code, and since I can’t reproduce it, I can’t troubleshoot it.
Check to see that the arguments to the duration function are the simple integers it requires for each argument. Then, see if the duration call works with the same vectors. That’s the only approach I can think of to determine what the problem is.
EDIT — (26 Mar 2022 at 21:50)
The only other possibility that I can think of is that you have an ‘hour’, ‘minute’, or ‘second’ array that is overshadowing the MATLAB functions by those names.
Run:
which hour -all
/MATLAB/toolbox/matlab/timefun/hour.m
/MATLAB/toolbox/matlab/datatypes/datetime/@datetime/datetime.m % Shadowed datetime method
/MATLAB/toolbox/matlab/bigdata/@tall/hour.m % Shadowed tall method
/MATLAB/toolbox/parallel/parallel/@codistributed/hour.m % Shadowed codistributed method
and do the same for each of the others. If the first entry in the output of that call is:
hour is a variable.
or something similar, that is the problem. The solution is to re-name the variable to something that makes sense in the context of the code, and does not overshadow any MATLAB functions.
.
More Answers (1)
Simon Chan
on 26 Mar 2022
Do you accept not using function timerange as follows?
T = readtable('date.txt')
T = 18×1 table
Var1
___________________
2015-11-08 12:00:00
2015-11-08 13:01:00
2015-11-08 14:02:00
2015-11-08 15:03:00
2015-11-08 17:00:00
2015-11-08 17:00:01
2015-11-08 18:04:00
2015-11-08 19:04:00
2015-11-08 20:05:00
2015-11-08 21:06:00
2015-11-08 22:07:00
2015-11-08 23:08:00
2015-11-09 00:09:00
2015-11-09 02:10:00
2015-11-09 07:10:00
2015-11-09 08:10:00
T.Var1(hour(T.Var1)<9 | hour(T.Var1)>=17 & ~(hour(T.Var1)>=17 & minute(T.Var1)==0 & second(T.Var1)==0))
ans = 11×1 datetime array
2015-11-08 17:00:01
2015-11-08 18:04:00
2015-11-08 19:04:00
2015-11-08 20:05:00
2015-11-08 21:06:00
2015-11-08 22:07:00
2015-11-08 23:08:00
2015-11-09 00:09:00
2015-11-09 02:10:00
2015-11-09 07:10:00
2015-11-09 08:10:00
1 Comment
Thank you for this answer.
Kevin
Categories
Find more on Introduction to Installation and Licensing in Help Center and File Exchange
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)