# Extend a cell array of dates (from days only, to hours and days) in a compact way

1 view (last 30 days)
Sim on 17 May 2022
Commented: Sim on 18 May 2022
I have a cell vector containing 44 dates, i.e. days:
>> C
ans =
44×1 cell array
{'17-Jun-2017'}
{'18-Jun-2017'}
{'19-Jun-2017'}
...
{'28-Jul-2017'}
{'29-Jul-2017'}
{'30-Jul-2017'}
I would like to "extend" that cell vector to include the 24 hours as well, in each day.
This means that my cell vector will pass from 44 elements (i.e. the 44 days) to 24 * 44 = 1056 elements (i.e. 24 hours in each day). Something like this:
% Desired Output (something like this)
>> D
ans =
1056×1 cell array
{'17-Jun-2017 00:00:00'}
{'17-Jun-2017 01:00:00'}
{'17-Jun-2017 02:00:00'}
...
{'17-Jun-2017 23:00:00'}
{'18-Jun-2017 00:00:00'}
{'18-Jun-2017 01:00:00'}
{'18-Jun-2017 02:00:00'}
...
{'29-Jul-2017 23:00:00'}
{'30-Jul-2017 00:00:00'}
Any idea on how to do it in a compact way ?
Maybe there is a simple in-built function in Matlab to do that, and that I am probably missing right now..

Star Strider on 17 May 2022
Edited: Star Strider on 17 May 2022
Try this —
C1 = {'17-Jun-2017'; '30-Jul-2017'}
C1 = 2×1 cell array
{'17-Jun-2017'} {'30-Jul-2017'}
DT1 = [datetime(C1{1}) : days(1) : datetime(C1{end})]'
DT1 = 44×1 datetime array
17-Jun-2017 18-Jun-2017 19-Jun-2017 20-Jun-2017 21-Jun-2017 22-Jun-2017 23-Jun-2017 24-Jun-2017 25-Jun-2017 26-Jun-2017 27-Jun-2017 28-Jun-2017 29-Jun-2017 30-Jun-2017 01-Jul-2017 02-Jul-2017 03-Jul-2017 04-Jul-2017 05-Jul-2017 06-Jul-2017 07-Jul-2017 08-Jul-2017 09-Jul-2017 10-Jul-2017 11-Jul-2017 12-Jul-2017 13-Jul-2017 14-Jul-2017 15-Jul-2017 16-Jul-2017
DT2 = [min(DT1): hours(1) : max(DT1)]'
DT2 = 1033×1 datetime array
17-Jun-2017 00:00:00 17-Jun-2017 01:00:00 17-Jun-2017 02:00:00 17-Jun-2017 03:00:00 17-Jun-2017 04:00:00 17-Jun-2017 05:00:00 17-Jun-2017 06:00:00 17-Jun-2017 07:00:00 17-Jun-2017 08:00:00 17-Jun-2017 09:00:00 17-Jun-2017 10:00:00 17-Jun-2017 11:00:00 17-Jun-2017 12:00:00 17-Jun-2017 13:00:00 17-Jun-2017 14:00:00 17-Jun-2017 15:00:00 17-Jun-2017 16:00:00 17-Jun-2017 17:00:00 17-Jun-2017 18:00:00 17-Jun-2017 19:00:00 17-Jun-2017 20:00:00 17-Jun-2017 21:00:00 17-Jun-2017 22:00:00 17-Jun-2017 23:00:00 18-Jun-2017 00:00:00 18-Jun-2017 01:00:00 18-Jun-2017 02:00:00 18-Jun-2017 03:00:00 18-Jun-2017 04:00:00 18-Jun-2017 05:00:00
C2 = compose('%s',string(DT2))
C2 = 1033×1 cell array
{'17-Jun-2017 00:00:00'} {'17-Jun-2017 01:00:00'} {'17-Jun-2017 02:00:00'} {'17-Jun-2017 03:00:00'} {'17-Jun-2017 04:00:00'} {'17-Jun-2017 05:00:00'} {'17-Jun-2017 06:00:00'} {'17-Jun-2017 07:00:00'} {'17-Jun-2017 08:00:00'} {'17-Jun-2017 09:00:00'} {'17-Jun-2017 10:00:00'} {'17-Jun-2017 11:00:00'} {'17-Jun-2017 12:00:00'} {'17-Jun-2017 13:00:00'} {'17-Jun-2017 14:00:00'} {'17-Jun-2017 15:00:00'} {'17-Jun-2017 16:00:00'} {'17-Jun-2017 17:00:00'} {'17-Jun-2017 18:00:00'} {'17-Jun-2017 19:00:00'} {'17-Jun-2017 20:00:00'} {'17-Jun-2017 21:00:00'} {'17-Jun-2017 22:00:00'} {'17-Jun-2017 23:00:00'} {'18-Jun-2017 00:00:00'} {'18-Jun-2017 01:00:00'} {'18-Jun-2017 02:00:00'} {'18-Jun-2017 03:00:00'} {'18-Jun-2017 04:00:00'} {'18-Jun-2017 05:00:00'}
It simply creates a new datetime vector with a different increment from the original cell array, and then uses the compose function to create a new cell array from that. (I would keep it as a datetime array rather than converting it back to a cell array.)
.
Star Strider on 17 May 2022
As always, my pleasure!

Mitch Lautigar on 17 May 2022
Use for loops. Here's an untested example of what I mean.
stack_array = [];
for i = 1:length(C)
curr_date = C(i);
for j = 1:24
stack_array = [stack_array;cell(strjoin(cellstr(curr_date),'-',num2str(j)) )];
end
end
In theory, this code would loop through and for every date in your C loop, add in the hours with a dash in the middle to keep the formatting you have above. Hope it helps!
##### 2 CommentsShowHide 1 older comment
Sim on 17 May 2022
this works for me:
D = [];
k = 1;
for i = 1:length(C)
for j = 0:23
D{k} = strjoin([C(i),sprintf('%d:00:00',j)]);
k = k + 1;
end
end
which gives:
>> D
Columns 1053 through 1055
{'30-Jul-2017 20:00:00'} {'30-Jul-2017 21:00:00'} {'30-Jul-2017 22:00:00'}
Column 1056
{'30-Jul-2017 23:00:00'}
But I was thinking if there is a more compact way.... I mean not using the loop for....

Mitch Lautigar on 17 May 2022
stack_array = [stack_array;cell(strjoin(cellstr(curr_date),'-',num2str(j)) )]; should be:
stack_array = [stack_array; cell(strjoin(cellstr(curr_date),'-',num2str(j),'') )]; forgot to tell strjoin how to join the command.
Sim on 17 May 2022
thanks a lot @Mitch Lautigar for the amendment, very kind!

Steven Lord on 17 May 2022
I'd probably take advantage of implicit expansion for datetime and duration arrays, introduced for those types in release R2020b.
C = {'17-Jun-2017'; '18-Jun-2017'; '19-Jun-2017'}
C = 3×1 cell array
{'17-Jun-2017'} {'18-Jun-2017'} {'19-Jun-2017'}
theDays = datetime(C).'
theDays = 1×3 datetime array
17-Jun-2017 18-Jun-2017 19-Jun-2017
theHours = hours(0:23).'
theHours = 24×1 duration array
0 hr 1 hr 2 hr 3 hr 4 hr 5 hr 6 hr 7 hr 8 hr 9 hr 10 hr 11 hr 12 hr 13 hr 14 hr 15 hr 16 hr 17 hr 18 hr 19 hr 20 hr 21 hr 22 hr 23 hr
D = theDays + theHours; % Adding a row vector and a column vector gives a matrix
D = reshape(D, [], 1)
D = 72×1 datetime array
17-Jun-2017 00:00:00 17-Jun-2017 01:00:00 17-Jun-2017 02:00:00 17-Jun-2017 03:00:00 17-Jun-2017 04:00:00 17-Jun-2017 05:00:00 17-Jun-2017 06:00:00 17-Jun-2017 07:00:00 17-Jun-2017 08:00:00 17-Jun-2017 09:00:00 17-Jun-2017 10:00:00 17-Jun-2017 11:00:00 17-Jun-2017 12:00:00 17-Jun-2017 13:00:00 17-Jun-2017 14:00:00 17-Jun-2017 15:00:00 17-Jun-2017 16:00:00 17-Jun-2017 17:00:00 17-Jun-2017 18:00:00 17-Jun-2017 19:00:00 17-Jun-2017 20:00:00 17-Jun-2017 21:00:00 17-Jun-2017 22:00:00 17-Jun-2017 23:00:00 18-Jun-2017 00:00:00 18-Jun-2017 01:00:00 18-Jun-2017 02:00:00 18-Jun-2017 03:00:00 18-Jun-2017 04:00:00 18-Jun-2017 05:00:00
Sim on 18 May 2022
Oh great @Steven Lord !!
Amazing, thanks a lot! :-)