# Sorting specific dates from Datetime array

9 views (last 30 days)
Me on 11 Jul 2020
Commented: Steven Lord on 14 Jul 2020
Hello,
I have a Datetime array (size: 1x1200) in the form of: 'dd-MMM-uuuu HH:mm:ss'
This array is allready orgenized by date & time from oldest sample to newer sample. I.e. Date(1,1) = oldest sample ; Date(1,1200) = Current time/day.
The sampling process is done randomaly. Thus, on a given date I could have a few samples (on differant hours of the day..) or none at all.
I have 2 user inputs: DateStart and DateEnd. Both are text inputs in the form of "dd/MM/uu".
I need to check which samples occured between DateStart to DateEnd (Including those days). DateStart and DateEnd can be the same date.
I tried searching for the specific dates but beacuse my array also shows the time (and I input date only) I get zero results...
% I converted the user input into datetime format.. then:
any(Date=='22-Apr-2020')
% This returns logic 0 result even though this day exist in Date...
% Next, I tried specific date:
any(Date=='22-Apr-2020 03:54:57')
% This works OK and returns logic 1.
So, I tried sorting it by logocal operators:
Smp1 = Date > DateCheckEnd;
Smp2 = Date < DateCheckStart;
SmpTotal = ~(Smp1 | Smp2 )
But this does not work well becuase the dates for DateCheckEnd are not being included.
I'm guessing that my input without hours defults to '22-Apr-2020 00:00:00' and so all the later samples that date being excluded.
I tried by changing to: Date.Format = 'dd-MMM-uuuu'
But this keeps the data of the time. and thus, still does not work.
Any suggestions how to resolve this?

Steven Lord on 11 Jul 2020
Let's create some sample time and date data spanning from five hours (300 minutes) ago to four hours (240 minutes) from now.
N = datetime('now');
dt = N + minutes(randi([-300 240], 30, 1));
Which of those took place between three hours ago and two hours from now? If we use the <= and >= operators we can include the end points.
earlyEndpoint = N - hours(3);
laterEndpoint = N + hours(2);
isinrange = (earlyEndpoint <= dt) & (dt <= laterEndpoint);
timesInRange = dt(isinrange);
timesNotInRange = dt(~isinrange);
howFarFromCenterInRange = timesInRange - N;
howFarFromCenterOutOfRange = timesNotInRange - N;
Let's put the results in table arrays for easy display.
allInRange = table(timesInRange, howFarFromCenterInRange)
allOutOfRange = table(timesNotInRange, howFarFromCenterOutOfRange)

Show 1 older comment
Steven Lord on 11 Jul 2020
The key line is this one:
isinrange = (earlyEndpoint <= dt) & (dt <= laterEndpoint);
A particular element of isinrange will be true if the corresponding element of dt is greater than or equal to the datetime stored in earlyEndpoint AND less than or equal to the datetime stored in laterEndpoint. Then I use that to perform logical indexing into dt.
Me on 13 Jul 2020
Hi Steven,
Your answer works while searching date+time in a date+time array. That was not the quastion. The quastion was to appaly a search of date (only) in an date+time array.
Evantualy, I've just added '00:00:00' to the start date and "23:59:59" to the end date and redid the search...
UserInputStart = '22-Apr-2020';
DateCheckStart = [UserInputStart, ' 00:00:00'];
UserInputEnd = '05-May-2020';
DateCheckEnd = [UserInputEnd,' 23:59:59'];
% Then, check..
Smp1 = Date > DateCheckEnd;
Smp2 = Date < DateCheckStart;
SmpTotal = ~(Smp1 | Smp2 )
% This works OK...
Steven Lord on 14 Jul 2020
dateonly = datetime('today')
dateAndTime = datetime('now')
dateAndTime > dateonly % true unless dateAndTime was created at midnight
dateAndTime > (dateonly + days(1))

Stephen Cobeldick on 13 Jul 2020
Edited: Stephen Cobeldick on 13 Jul 2020
This is easy using datetime and days:
>> vd = linspace(days(-2),days(2),10);
>> dt = datetime+vd(:)
dt =
12-Jul-2020 00:48:23
12-Jul-2020 11:28:23
12-Jul-2020 22:08:23
13-Jul-2020 08:48:23
13-Jul-2020 19:28:23
14-Jul-2020 06:08:23
14-Jul-2020 16:48:23
15-Jul-2020 03:28:23
15-Jul-2020 14:08:23
16-Jul-2020 00:48:23
>> bd = datetime('2020-07-13');
>> ed = datetime('2020-07-15');
>> ix = dt>=bd & dt<ed+days(1)
ix =
0
0
0
1
1
1
1
1
1
0